欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# Fleck的WebSocket使用

程序员文章站 2022-06-25 09:33:15
一.基础知识(Foundation) (1). WebSocket介绍 WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服...

一.基础知识(Foundation)

(1). WebSocket介绍

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

(2).浏览器对WebSocket的支持
C# Fleck的WebSocket使用
(3)WebSocket服务器支持
C# Fleck的WebSocket使用

(4). Web前端知识概要

<1>. 对象创建(调用WebSocket的构造函数)

1)函数原型:

Constructor(DOMString url,[DOMString protocols]);

2)说明:url为WebSocket服务器的地址,protocols为发起握手的协议名称,为可选择项。

<2>. 接口及函数方法(WebSocket的接口的定义)

1)函数原型:

Interface WebSocket:EventTarget{
	readonly attribute DOMString url;
	//readyState状态值
	Const unsigned short CONNECTING=0;
	Const unsigned short OPEN=1;
	Const unsigned short CLOSING=2;
	Const unsigned short CLOSED=3;
	readonly attribute unsigned short readyState;
	readonly attribute unsigned long bufferedAmount;
	//监听网络状态的事件监听器属性
	[TreatNonCallableAsNull] attribute Function? onopen;
	[TreatNonCallableAsNull] attribute Function? onerror;
        [TreatNonCallableAsNull] attribute Function? onclose;
	readonly attribute DOMString extensions;
	readonly attribute DOMString protocol;
	//关闭网络连接的方法
	void close([Clamp] optional unsigned short code,optional DOMString reason);
	//接受服务器消息的事件监听器函数
	[TreatNonCallableAsNull] attribute Function? onmessage;
	attribute DOMString binaryType;
	void send(DOMString data);
	void send(ArrayBuffer data);
	void send(Blob data);
};

2)说明:
【1】. 两个方法:

    ● send():向远程服务器发送数据
    ● cosle():关闭该WebSocket

【2】. 四个重要的事件监听器属性:

    ● onopen:当WebSocket建立网络连接的时候触发该事件
    ● onerror:当网络连接出现问题的时候触发该事件
    ● onclose:当WebSocket被关闭的时候触发该事件
    ● onmessage:当WebSocket接受到远程服务器的数据的时候触发该事件

            注意:1. 上面的四个函数名均为小写,大小写时敏感的;
                      2. onmessage 绑定一个型为 function(event){…} 的函数这样就可以通过event.data来获得返回的数据;


【3】. readyState属性,用于返回WebSocket所处的状态:

    ● CONNECTING(数值0):WebSocket正在尝试与服务器建立连接
    ● OPEN(数值1):WebSocket与服务器已经建立连接
    ● CLOSING(数值2):WebSocket正在关闭与服务器的连接
    ● CLOSED(数值3):WebSocket已经关闭了与服务器的连接

<3>. 使用WebSocket(4步)

1) 将相关的定义函数绑定到上面4个监听事件中;

2) 调用WebSocket的构造函数,给定一个url来初始化一个WebSocket对象;

3) 通过send()方法来发送数据;

4) 在有必要的时候可以用close()来关闭监听;

(5).客户端知识概要

<1>. 梗概

我们可以通过基础的Socket通信来实现和网页的相互通信。但由于只有在.net Framework在4.5以及4.5以上的版本对WebSocket通信的数据解析才有相关的类来支持。所以解析数据写起来十分的繁琐,所以我们使用第三方的库来完成低版本.net框架中的通信。如果有时间我也会写一篇有关socket来进行通信及解析数据的文章。

接下来我看看用的软件和相关的技术知识。

<2>. .Net不同WebSocket库的比较

我这里找了一下网上的资料,如下链接,如果仅仅是要从网页发送消息到服务器,那么我这边使用Flerk。

● 英文版:WebSocket libraries comparison
● 翻译版:.NET的WebSocket开发包比较【已翻译100%】

<3>. Fleck的源码下载以及说明文档

源码可以从网上下载,这里我给出链接:源码下载

点击页面中的Clone or download -> Download ZIP,如下
C# Fleck的WebSocket使用
图一
说明文档就在下载的下面,是英文版的的。

二.代码(Code)

(1). Web网页端代码

<!DOCTYPE html>
 
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>WebSocket测试</title>
    <style>
        .div1
        {
            height:88px;   
            width:173px;
            border:1px solid blue;
            margin:auto;
        }
        h4
        {
            margin:auto;
        }
    </style>
    <script>
        var webSocket = {};
        //创建websockt
        function CreateWebSocket() {
            webSocket = new WebSocket("ws://127.0.0.1:30000");
            webSocket.onopen = WebSokectOnOpen;
            webSocket.onmessage = WebSocketOnMessage;
            webSocket.onclose = WebSocketOnClose;
        };
 
        //建立连接事件
        function WebSokectOnOpen() {
            alert("已经打开连接!");
            webSocket.Send("WebSocketCreate Success!");
        };
 
        //监听事件
        function WebSocketOnMessage(event) {
            //监听来自客户端的数据
            alert(event.data);
        };
 
        function WebSocketOnClose() {
            //监听来自客户端的数据
            alert('和服务器断开连接');
        };
 
        //发送事件
        function WebSocketSendMsg() {
            //获取text中的值
            var text = document.getElementById("Text1").value;
            //发送到服务器
            webSocket.send(text);
        };
    </script>
</head>
<body οnlοad="CreateWebSocket()">
    <div class="div1">
        <h4>CSDN博客</h4>
        <h4>By:LoveMiw</h4>
        <input type="text" id="Text1" />
        <input type="button" οnclick="WebSocketSendMsg()" value="发送数据" />
    </div>
</body>
</html>

(2). 服务端C#代码
//上面是程序生成的using

using Fleck;
 
namespace WebSocketTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //客户端url以及其对应的Socket对象字典
            IDictionary<string, IWebSocketConnection> dic_Sockets = new Dictionary<string, IWebSocketConnection>();
            //创建
 
            WebSocketServer server = new WebSocketServer("ws://0.0.0.0:30000");//监听所有的的地址
            //出错后进行重启
            server.RestartAfterListenError = true;
 
            //开始监听
            server.Start(socket =>
            {
                socket.OnOpen = () =>   //连接建立事件
                {
                    //获取客户端网页的url
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    dic_Sockets.Add(clientUrl, socket);
                    Console.WriteLine(DateTime.Now.ToString() + "|服务器:和客户端网页:" + clientUrl + " 建立WebSock连接!");
                };
                socket.OnClose = () =>  //连接关闭事件
                {
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    //如果存在这个客户端,那么对这个socket进行移除
                    if (dic_Sockets.ContainsKey(clientUrl))
                    {
                        //注:Fleck中有释放
                        //关闭对象连接 
                        //if (dic_Sockets[clientUrl] != null)
                        //{
                            //dic_Sockets[clientUrl].Close();
                        //}
                        dic_Sockets.Remove(clientUrl);
                    }
                    Console.WriteLine(DateTime.Now.ToString() + "|服务器:和客户端网页:" + clientUrl + " 断开WebSock连接!");
                };
                socket.OnMessage = message =>  //接受客户端网页消息事件
                {
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    Console.WriteLine(DateTime.Now.ToString() + "|服务器:【收到】来客户端网页:" + clientUrl + "的信息:\n" + message);
                };
            });
 
            Console.ReadKey();
            foreach (var item in dic_Sockets.Values)
            {
                if (item.IsAvailable == true)
                {
                    item.Send("服务器消息:" + DateTime.Now.ToString());
                }
            }
            Console.ReadKey();
 
            //关闭与客户端的所有的连接
            foreach (var item in dic_Sockets.Values)
            {
                if (item != null)
                {
                    item.Close();
                }
            }
 
            Console.ReadKey();
        }
    }
}

四. 结束语(Ending)
(1). 在Fleck上面下载的源码在放到工程中的时候似乎会报错,只要重新把所有的.cs按它原来的结构添加到一个新的工程中在编译就可以通过;

工程源代码(环境vs2015)

Fleck源代码