DYTcpService

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());
        }
    }
}

原文地址:https://www.cnblogs.com/jacle169/p/2998655.html