WebSocket聊天室Demo

1.WebSocket定义
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。

2.与Http协议区别
HTTP:超文本传输协议,首先它是一个协议,并且是基于TCP/IP协议基础之上的应用层协议。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,HTTP是应用层协议,主要解决如何包装数据。HTTP协议详细规定了浏览器与服务器之间相互通信的规则,是万维网交换信息的基础。HTTP是基于请求-响应形式并且是短连接,并且是无状态的协议。针对其无状态特性,在实际应用中又需要有状态的形式,因此一般会通过session/cookie技术来解决此问题。
Socket:Socket不属于协议范畴,而是一个调用接口(API),Socket是对TCP/IP协议的封装,通过调用Socket,才能使用TCP/IP协议。Socket连接是长连接,理论上客户端和服务器端一旦建立连接将不会主动断开此连接。Socket连接属于请求-响应形式,服务端可主动将消息推送给客户端。

3.聊天室
简单架构:C/S服务端+C/S客户端+B/S客户端

4.实现原理

我们可以尝试让Socket Server透明地支持WebSocket客户端,所谓透明的意思是,服务端开发人员不用关心客户端究竟是什么类型,而是可以统一的接收数据、处理数据、发送数据。为了做到这一点,我们可以构建一个服务端框架,让框架完成透明化的工作,这就要求这个框架做到以下几点:

(1)根据客户端TCP连接请求成功后的第一个消息中是否含有“websocket”标记,来判断其是否为WebSocket客户端。如果客户端的类型是WebSocket,则自动完成以下事情。

(2)自动完成Web Sokects 握手协议。

(3)针对接收到的每个WebSokect数据帧,都能自动将其解析,并从中分离出真正的消息内容。

(4)当您发送消息给WebSokect客户端时,服务端引擎会自动将该消息封装成WebSokect数据帧,然后再发送出去。

5.服务端核心代码实现
小程序市基于StriveEngine组件实现。
启动服务

 private void button1_Click(object sender, EventArgs e)
        {
            try
            {                
                if (this.tcpServerEngine == null)
                {
                    this.tcpServerEngine = NetworkEngineFactory.CreateTextTcpServerEngine(int.Parse(this.textBox_port.Text), new DefaultTextContractHelper("\0"));//DefaultTextContractHelper是StriveEngine内置的ITextContractHelper实现。使用UTF-8对EndToken进行编码。 
                }             

                if (this.hasTcpServerEngineInitialized)
                {                   
                    this.tcpServerEngine.ChangeListenerState(true);                    
                }
                else
                {
                    this.InitializeTcpServerEngine();                   
                }

                this.ShowListenStatus();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }

发送文本

 private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                IPEndPoint client = (IPEndPoint)this.comboBox1.SelectedItem;
                if (client == null)
                {
                    MessageBox.Show("没有选中任何在线客户端!");
                    return;
                }

                if (!this.tcpServerEngine.IsClientOnline(client))
                {
                    MessageBox.Show("目标客户端不在线!");
                    return;
                }

                string msg = this.textBox_msg.Text + "\0";// "\0" 表示一个消息的结尾
                byte[] bMsg = System.Text.Encoding.UTF8.GetBytes(msg);//消息使用UTF-8编码
                this.tcpServerEngine.SendMessageToClient(client, bMsg);
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }

6.C/S客户端核心代码实现
连接服务端

    private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                //初始化并启动客户端引擎(TCP、文本协议)
                this.tcpPassiveEngine = NetworkEngineFactory.CreateTextTcpPassiveEngine(this.textBox_IP.Text, int.Parse(this.textBox_port.Text), new DefaultTextContractHelper("\0"));
                this.tcpPassiveEngine.MessageReceived += new CbDelegate<System.Net.IPEndPoint, byte[]>(tcpPassiveEngine_MessageReceived);
                this.tcpPassiveEngine.AutoReconnect = true;//启动掉线自动重连                
                this.tcpPassiveEngine.ConnectionInterrupted += new CbDelegate(tcpPassiveEngine_ConnectionInterrupted);
                this.tcpPassiveEngine.ConnectionRebuildSucceed += new CbDelegate(tcpPassiveEngine_ConnectionRebuildSucceed);
                this.tcpPassiveEngine.Initialize();

                this.button2.Enabled = true;
                this.button3.Enabled = false;
                MessageBox.Show("连接成功!");
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }

发送文本

  private void button2_Click(object sender, EventArgs e)
        {
            string msg = this.textBox_msg.Text + "\0";// "\0" 表示一个消息的结尾
            byte[] bMsg = System.Text.Encoding.UTF8.GetBytes(msg);//消息使用UTF-8编码
            this.tcpPassiveEngine.SendMessageToServer(bMsg);
        }

7.B/S客户端实现
连接服务端

function connect() {
            var host = "ws://" + $("serverIP").value + ":" + $("serverPort").value + "/"
            socket = new WebSocket(host);
            try {

                socket.onopen = function (msg) {
                    $("btnConnect").disabled = true;
                    alert("连接成功!");
                };

                socket.onmessage = function (msg) {
                    if (typeof msg.data == "string") {
                        displayContent(msg.data);
                    }
                    else {
                        alert("非文本消息");
                    }
                };

                socket.onclose = function (msg) { alert("socket closed!") };
            }
            catch (ex) {
                log(ex);
            }
        }

发送文本


        function send() {
            var msg = $("sendText").value + '\0'
            socket.send(msg);
        }

8.效果图
启动服务端监听端口号9000,开启多个客户端实现连接,发送消息,连接状态是保持的,可以实现服务端和客户端互相推送消息!
这里写图片描述

原文链接:http://www.cnblogs.com/zhuweisky/p/3930780.html

猜你喜欢

转载自blog.csdn.net/sunbo_csdn/article/details/82503632