server:
//.net framework4.0 not profile
//destop app
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Collections;
using System.Threading;
namespace DYTcpService
{
public class serverDo : Imyserver
{
static Dictionary<string, Iclientcallback> clients = new Dictionary<string, Iclientcallback>();
public void login(string uid)
{
clients.Add(uid, OperationContext.Current.GetCallbackChannel<Iclientcallback>());
OperationContext.Current.Channel.Faulted += new EventHandler(Channel_Faulted);
OperationContext.Current.Channel.Closed += new EventHandler(Channel_Faulted);
List<Iclientcallback> sendList = null;
lock (((ICollection)clients).SyncRoot)
{
sendList = new List<Iclientcallback>(clients.Values);
}
if (sendList != null && sendList.Count > 0)
{
sendList.ForEach(i => ThreadPool.QueueUserWorkItem((o) =>
{
try { i.clientLogin(uid); }
catch { }
}, i));
}
}
internal static void SendToAllClients(string uid, string msg)
{
List<Iclientcallback> sendList = null;
lock (((ICollection)clients).SyncRoot)
{
sendList = new List<Iclientcallback>(clients.Values);
}
if (sendList != null && sendList.Count > 0)
{
sendList.ForEach(i => ThreadPool.QueueUserWorkItem((o) =>
{
try { i.clientSay(uid, msg); }
catch { }
}, i));
}
}
void Channel_Faulted(object sender, EventArgs e)
{
var tk = sender as IContextChannel;
tk.Faulted -= new EventHandler(Channel_Faulted);
tk.Closed -= new EventHandler(Channel_Faulted);
IContextChannel channel = (IContextChannel)sender;
if (channel != null)
{
string sessionId = channel.SessionId;
deleteClient(sessionId);
}
}
void deleteClient(string sessionId)
{
lock (((ICollection)clients).SyncRoot)
{
if (clients.ContainsKey(sessionId))
{
clients.Remove(sessionId);
}
}
}
public void say(string uid, string msg)
{
SendToAllClients(uid, msg);
}
public void logout(string uid)
{
List<Iclientcallback> sendList = null;
lock (((ICollection)clients).SyncRoot)
{
sendList = new List<Iclientcallback>(clients.Values);
}
if (sendList != null && sendList.Count > 0)
{
sendList.ForEach(i => ThreadPool.QueueUserWorkItem((o) =>
{
try { i.clientLogout(uid); }
catch { }
}, i));
}
}
}
[ServiceContract(CallbackContract = typeof(Iclientcallback))]
public interface Imyserver
{
[OperationContract(IsOneWay = true)]
void login(string uid);
[OperationContract(IsOneWay = true)]
void say(string uid, string msg);
[OperationContract(IsOneWay = true)]
void logout(string uid);
}
public interface Iclientcallback
{
[OperationContract(IsOneWay = true)]
void clientLogin(string uid);
[OperationContract(IsOneWay = true)]
void clientSay(string uid, string msg);
[OperationContract(IsOneWay = true)]
void clientLogout(string uid);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace DYTcpService
{
public class crossDomainDo : IPolicyRetriever
{
private Stream StringToStream(string result)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
return new MemoryStream(Encoding.UTF8.GetBytes(result));
}
public Stream GetSilverlightPolicy()
{
string result = @"<?xml version=""1.0"" encoding =""utf-8""?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri=""*"" />
</allow-from>
<grant-to>
<socket-resource port=""4502-4534"" protocol=""tcp"" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>";
return StringToStream(result);
}
}
[ServiceContract]
public interface IPolicyRetriever
{
[OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
Stream GetSilverlightPolicy();
}
}
namespace DYTcpService
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
NetTcpBinding nt = new NetTcpBinding();
nt.Security.Mode = SecurityMode.None;
nt.SendTimeout = new TimeSpan(0, 0, 2);
ServiceHost host = new ServiceHost(typeof(serverDo), new Uri("net.tcp://localhost:4502/tcp"));
host.AddServiceEndpoint(typeof(Imyserver), nt, "");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.HttpGetUrl = new Uri("http://localhost:4503/mex");
host.Description.Behaviors.Add(smb);
host.Open();
ServiceHost cdhost = new ServiceHost(typeof(crossDomainDo), new Uri("http://localhost:80"));
cdhost.AddServiceEndpoint(typeof(IPolicyRetriever), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
cdhost.Open();
this.Title = host.State.ToString();
}
}
}
client:
//Silverlight 4 or silverlight5
//web services reference http://localhost:4503/mex
xaml:
<Grid x:Name="LayoutRoot" Background="White">
<TextBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="295" />
<Button Content="login" Height="23" HorizontalAlignment="Left" Margin="313,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
<ListBox Height="217" HorizontalAlignment="Left" Margin="12,42,0,0" Name="listBox1" VerticalAlignment="Top" Width="376" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="12,265,0,0" Name="textBox2" VerticalAlignment="Top" Width="295" />
<Button Content="send" Height="23" HorizontalAlignment="Left" Margin="313,265,0,0" Name="button2" VerticalAlignment="Top" Width="75" />
</Grid>
cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ServiceModel;
namespace DYTcpClient
{
public partial class MainPage : UserControl, ServiceReference1.ImyserverCallback
{
ServiceReference1.ImyserverClient sv;
public MainPage()
{
InitializeComponent();
button1.Click += new RoutedEventHandler(button1_Click);
button2.Click += new RoutedEventHandler(button2_Click);
sv = new ServiceReference1.ImyserverClient(new InstanceContext(this));
}
private void button1_Click(object sender, RoutedEventArgs e)
{
sv.loginAsync(textBox1.Text);
}
private void button2_Click(object sender, RoutedEventArgs e)
{
sv.sayAsync(textBox1.Text, textBox2.Text);
}
public void clientLogin(string uid)
{
listBox1.Items.Insert(0, uid + " login at: " + DateTime.Now.ToString());
}
public void clientSay(string uid, string msg)
{
listBox1.Items.Insert(0, uid + ": " + msg);
}
public void clientLogout(string uid)
{
listBox1.Items.Insert(0, uid + " leave at: " + DateTime.Now.ToString());
}
}
}