在Silverlight中使用Socket进行通信(3)简单的文本聊天工具

在Silverlight中使用Socket进行通信(3)简单的文本聊天工具,第1张

概述在上一篇的基础上,晚上我又尝试了一下做个聊天工具,有个定时取消息的过程解决不好,明天再研究一下,在这个文本聊天的基础上,稍加扩展就可以进行视频聊天了,下一篇将会做silverlight视频聊天的DEMO. 整体效果是        还是从服务端说起,服务端做中转消息用,为了模拟聊天情景,服务端简单写了一个实体用来缓存聊天内容  代码 public   class  UserSocket      

在上一篇的基础上,晚上我又尝试了一下做个聊天工具,有个定时取消息的过程解决不好,明天再研究一下,在这个文本聊天的基础上,稍加扩展就可以进行视频聊天了,下一篇将会做silverlight视频聊天的DEMO.

整体效果是

 

   

 

还是从服务端说起,服务端做中转消息用,为了模拟聊天情景,服务端简单写了一个实体用来缓存聊天内容 

代码 public   class  UserSocket 
    { 
        
public   string  Username {  set get ; } 
        
public   string  Partnername {  set get ; }         
        
public   string  Message {  set get ; } 
        
public  DateTime StoreTime {  set get ; } 
    }

  

然后在主程序中声明一个List<UserSocket>对象存储聊天内容。

static List<UserSocket> ListUserSocket = new List<UserSocket>();

当聊天双方给对方发送消息时,可以通过预先设定的字符串格式,比如采用 - 来将发送者,接受者,聊天内容组合起来发送到服务器进行解析和存储。

 

代码

byte [] bytData  =   new   byte [ 1024 ]; 
                
int  receivedLength  =  clIEnt.Receive(bytData); 
                
string  strReceive  =  System.Text.EnCoding.UTF8.GetString(bytData,  0 , receivedLength); 

                ListUserSocket.Add(
new  UserSocket() 
                { Username 
=  strReceive.Split( ' - ' )[ 0 ], 
                    Partnername 
=  strReceive.Split( ' - ' )[ 1 ], 
                    Message 
=  strReceive.Split( ' - ' )[ 2 ], 
                    StoreTime
= DateTime.Now });

 

 当客户端A定时来服务器请求发给自己的消息时,服务器就会在ListUserSocket中查找到发送给A的消息并清除此消息。

 

代码

UserSocket userSocket  =  ListUserSocket.Where(m  =>  m.Partnername  ==  strReceive.Split( ' - ' )[ 0 ]).FirstOrDefault(); 
                ListUserSocket.RemoveAll(m 
=>  m.Partnername  ==  strReceive.Split( ' - ' )[ 0 ]);

 

 关键代码:

由于silverlight中没有提供监听socket请求的方法,只能作为客户端跟服务器进行交互,所以在客户端我们可以预先定义一个Socket

 

private   Socket clIEntSocket  =   null ;  

 及远程通信的IP和端口 

private   const   string  SERVER_IP  =   " 127.0.0.1 "
        
private   const   int  SERVER_PORT  =   4530 ;

 我们可以为这个clIEntSocket建立起连接 

代码 clIEntSocket  =   new  Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
            socketasynceventargs socketEventArg 
=   new  socketasynceventargs() 
            { 
                RemoteEndPoint 
=   new  IPEndPoint(IPAddress.Parse(SERVER_IP), SERVER_PORT) 
            }; 
            socketEventArg.Completed 
+= new  EventHandler < socketasynceventargs > (socketEventArg_Completed); 
            clIEntSocket.ConnectAsync(socketEventArg);

 

鉴于sl的事件处理是异步的,所以 

代码 //  连接成功后 开始发送 
         voID  socketEventArg_Completed( object  sender, socketasynceventargs e) 
        { 
            
if  (e.socketError  ==  SocketError.Success) 
            { 
                
// AddText("已连接服务器!"); 
                 string  strSend  =  USERname + " - " + PARTNERname + " - " + MESSAGE; 
                
byte [] bytSend  =  EnCoding.UTF8.GetBytes(strSend); 
                socketasynceventargs socketArg 
=   new  socketasynceventargs(); 
                socketArg.Completed 
+=   new  EventHandler < socketasynceventargs > (socketArg_Completed); 
                socketArg.SetBuffer(bytSend, 
0 , bytSend.Length); 
                clIEntSocket.SendAsync(socketArg); 
                
// AddText("向服务器发送信息...");                
            }            
        }

  

当发送成功后,就可以向服务器取消息啦 

代码 voID  socketArg_Completed( object  sender, socketasynceventargs e) 
        { 
             
// 发送成功 
             if  (e.socketError  ==  SocketError.Success) 
            { 
                AddText(
" 已经将自己的IP和聊天对象发送到服务器 " ); 
            } 
            timer 
=   new  Timer( new  TimerCallback(StartReceive),  null 500 1000 );            
        }

  

定时取消息的方法,也是异步的 

代码 voID  StartReceive( object  o) 
        { 
            
byte [] byteReceive = new   byte [ 102400 ]; 
            socketasynceventargs socketReceiveArg 
=   new  socketasynceventargs(); 
            socketReceiveArg.Completed 
+=   new  EventHandler < socketasynceventargs > (socketReceiveArg_Completed); 
            socketReceiveArg.SetBuffer(byteReceive, byteReceive.Length); 
            clIEntSocket.ReceiveAsync(socketReceiveArg); 
        } 
        
voID  socketReceiveArg_Completed( object  sender, socketasynceventargs e) 
        { 
            
if  (e.socketError  ==  SocketError.Success) 
            { 
                
byte [] byteReceive  =  e.Buffer; 
                
string  strText  =  System.Text.EnCoding.UTF8.GetString(byteReceive, byteReceive.Length); 
                AddText(
" 成功接收到服务器回传的消息 "   +  strText); 
            } 
        } 

 可以看到,从连接到发送,再到接收,我们用的是一个socket实例来完成的,也就是说在silverlight中只需要连接一次socket就可以顺利进行后续 *** 作了。

服务端的监听

服务端的监听socket 跟客户端的不同,监听是一个socket实例,发送和接收则是另外一个代表客户端的实例。

首先还是需要指定监听IP和端口及使用的Socket

 

private   const   string  SERVER_IP  =   " 127.0.0.1 "
        
private   const   int  SERVER_PORT  =   4530
        
static  Socket Listener;

  

同样,也需要进行策略文件的验证 

代码 #region  Start The Policy Server 
                PolicySocketServer StartPolicyServer 
=   new  PolicySocketServer(); 
                Thread th 
=   new  Thread( new  ThreadStart(StartPolicyServer.StartSocketServer)); 
                th.IsBackground 
=   true
                th.Start(); 
                
#endregion

 

 然后开始监听 

代码 IPEndPoint localEndPoint  =   new  IPEndPoint(IPAddress.Parse(SERVER_IP), SERVER_PORT); 
                Listener 
=   new  Socket(AddressFamily.InterNetwork, ProtocolType.Tcp); 
                Listener.Bind(localEndPoint); 
                Listener.Listen(
- 1 ); 
                Console.Writeline(
" 等待客户端连接... " ); 
                
while  ( true
                { 
                    Socket clIEntSocket 
=  Listener.Accept(); 
                    
if  (clIEntSocket.Connected) 
                    {                     
                        Thread myThread 
=   new  Thread( new  ParameterizedThreadStart(SocketThread)); 
                        myThread.Start(clIEntSocket); 
                    } 
                } 

 

 当监听到有客户端连接时,就另外开启线程进行处理,这个 *** 作同时也确定了需要多个socket实例进行应答。 

代码 static   voID  SocketThread( object  clIEntSocket)   
        { 
            
try  
            { 
                Socket clIEnt 
=  (Socket)clIEntSocket; 
                IPEndPoint address 
=  (IPEndPoint)clIEnt.RemoteEndPoint; 

                
byte [] bytData  =   new   byte [ 1024 ]; 
                
int  receivedLength  =  clIEnt.Receive(bytData); 
                
string  strReceive  =  System.Text.EnCoding.UTF8.GetString(bytData, receivedLength); 

                ListUserSocket.Add(
new  UserSocket() 
                { Username 
=  strReceive.Split( ' - ' )[ 0 ], 
                    Partnername 
=  strReceive.Split( ' - ' )[ 1 ], 
                    Message 
=  strReceive.Split( ' - ' )[ 2 ], 
                    StoreTime
= DateTime.Now }); 
                Console.Writeline(
" "   +  strReceive.Split( ' - ' )[ 0 +   " 】通过【 "   +  address.Address.ToString()  +   " : "   +  address.Port.ToString()  +   " 】登录了服务器,并给【 "   +  strReceive.Split( ' - ' )[ 1 +   " 】留言如下: " ); 
                Console.Writeline(strReceive.Split(
' - ' )[ 2 ] + " ,当前服务器消息数量【: " + ListUserSocket.Count.ToString() + " " ); 

                UserSocket userSocket 
=  ListUserSocket.Where(m  =>  m.Partnername  ==  strReceive.Split( ' - ' )[ 0 ]).FirstOrDefault(); 
                ListUserSocket.RemoveAll(m 
=>  m.Partnername  ==  strReceive.Split( ' - ' )[ 0 ]); 
                
if  (userSocket  !=   null
                { 
                    clIEnt.Send(System.Text.EnCoding.UTF8.GetBytes(userSocket.Message)); 
                    Console.Writeline(
" "   +  userSocket.Partnername  +   " 】取走了消息【 "   +  userSocket.Message  +   " 】,当前服务器消息数量【: " + ListUserSocket.Count.ToString() + " " ); 
                } 
            } 
            
catch               {   }          }  总结

以上是内存溢出为你收集整理的在Silverlight中使用Socket进行通信(3)简单的文本聊天工具全部内容,希望文章能够帮你解决在Silverlight中使用Socket进行通信(3)简单的文本聊天工具所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1028017.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存