天天看点

C#工作总结(一):Fleck的WebSocket使用

一.引子(Foreword)

      最近公司里面要做窗体和网页交互的功能。网上找了一下资料,这里做一个简单的扩充和整理,部分内容可能是摘自其他博客,这里会注明出处和原文地址供大家和自己日后查阅。

二.基础知识(Foundation)

(1). WebSocket介绍

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

(2).浏览器对WebSocket的支持

浏览器 支持情况
Chrome谷歌浏览器 Chrome version 4+支持
Firefox火狐浏览器 Firefox version 5+支持
IE微软浏览器 IE version 10+支持(我们一般win7自带的是IE11)
Safari苹果浏览器 IOS 5+支持
Android Brower安卓浏览器 Android 4.5+支持

(3). WebSocket服务器支持

厂商 应用服务器 备注
IBM WebSphere WebSphere 8.0以上版本支持,7.X之前版本结合MQTT支持类似的HTTP长连接
甲骨文 WebLogic WebLogic 12c 支持,11g以及10g版本通过HTTP Publish支持类似的HTTP长连接
微软 IIS IIS 7.0+支持
Apache Tomcat Tomcat 7.0.5+支持
Jetty Jetty 7.0+支持

(4). Web前端知识概要

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

  1)函数原型:     

[javascript] ​​view plain​​​ ​​copy​​

  1. Constructor(DOMString url,[DOMString protocols]);

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

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

  1)函数原型:

[javascript] ​​view plain​​​ ​​copy​​

1. Interface<span style="color:#333333;"> </span>WebSocket:EventTarget{
2. readonly attribute DOMString url;
3. //readyState状态值
4. short CONNECTING=0;
5. short OPEN=1;
6. short CLOSING=2;
7. short CLOSED=3;
8. short readyState;
9. long bufferedAmount;
10. //监听网络状态的事件监听器属性
11. [TreatNonCallableAsNull] attribute Function? onopen;
12. [TreatNonCallableAsNull] attribute Function? onerror;
13. [TreatNonCallableAsNull] attribute Function? onclose;
14. readonly attribute DOMString extensions;
15. readonly attribute DOMString protocol;
16. //关闭网络连接的方法
17. void close([Clamp] optional unsigned short code,optional DOMString reason);
18. //接受服务器消息的事件监听器函数
19. [TreatNonCallableAsNull] attribute Function? onmessage;
20. attribute DOMString binaryType;
21. void send(DOMString data);
22. void send(ArrayBuffer data);
23. void send(Blob data);
24. };      

  2)说明:

        【1】. 两个方法:

            ● send():向远程服务器发送数据

            ● cosle():关闭该WebSocket

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

            ● onopen:当WebSocket建立网络连接的时候触发该事件

            ● onerror:当网络连接出现问题的时候触发该事件

            ● onclose:当WebSocket被关闭的时候触发该事件

            ● onmessage:当WebSocket接受到远程服务器的数据的时候触发该事件

                    注意:1. 上面的四个函数名均为小写,大小写时敏感的;

        【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()来关闭监听;

(4).客户端知识概要

<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,如下

图一

        说明文档就在下载的下面,是英文版的的,当然也可以看我博客中的译文:​​博主翻译版说明文档 (觉得不错的话转载一下哟:-》)​​

一.引子(Foreword)

        对于怎么使用直接看说明文档,非常简单,这里博主就不多说了。(博主都写到晚上1点了T T)

三.代码(Code)

(1). Web网页端代码

[html] ​​view plain​​​ ​​copy​​

1. <!DOCTYPE html>
2. 
3. <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
4. <head>
5. <meta charset="utf-8" />
6. <title>WebSocket测试</title>
7. <style>
8. .div1
9. {
10. height:88px;
11. width:173px;
12. border:1px solid blue;
13. margin:auto;
14. }
15. h4
16. {
17. margin:auto;
18. }
19. </style>
20. <script>
21. webSocket = {};
22. //创建websockt
23. function CreateWebSocket() {
24. webSocket = new WebSocket("ws://127.0.0.1:30000");
25. webSocket.onopen = WebSokectOnOpen;
26. webSocket.onmessage = WebSocketOnMessage;
27. webSocket.onclose = WebSocketOnClose;
28. };
29. 
30. //建立连接事件
31. function WebSokectOnOpen() {
32. alert("已经打开连接!");
33. webSocket.Send("WebSocketCreate Success!");
34. };
35. 
36. //监听事件
37. function WebSocketOnMessage(event) {
38. //监听来自客户端的数据
39. alert(event.data);
40. };
41. 
42. function WebSocketOnClose() {
43. //监听来自客户端的数据
44. alert('和服务器断开连接');
45. };
46. 
47. //发送事件
48. function WebSocketSendMsg() {
49. //获取text中的值
50. text = document.getElementById("Text1").value;
51. //发送到服务器
52. webSocket.send(text);
53. };
54. </script>
55. </head>
56. <body onload="CreateWebSocket()">
57. <div class="div1">
58. <h4>CSDN博客</h4>
59. <h4>By:LoveMiw</h4>
60. <input type="text" id="Text1" />
61. <input type="button" onclick="WebSocketSendMsg()" value="发送数据" />
62. </div>
63. </body>
64. </html>      

(2). 服务端C#代码

[csharp] ​​view plain​​​ ​​copy​​

1. //上面是程序生成的using
2. using Fleck;
3. 
4. namespace WebSocketTest
5. {
6. class Program
7. {
8. static void Main(string[] args)
9. {
10. //客户端url以及其对应的Socket对象字典
11. string, IWebSocketConnection> dic_Sockets = new Dictionary<string, IWebSocketConnection>();
12. //创建
13. 
14. new WebSocketServer("ws://0.0.0.0:30000");//监听所有的的地址
15. //出错后进行重启
16. true;
17. 
18. //开始监听
19. server.Start(socket =>
20. {
21. //连接建立事件
22. {
23. //获取客户端网页的url
24. string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
25. dic_Sockets.Add(clientUrl, socket);
26. "|服务器:和客户端网页:" + clientUrl + " 建立WebSock连接!");
27. };
28. //连接关闭事件
29. {
30. string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
31. //如果存在这个客户端,那么对这个socket进行移除
32. if (dic_Sockets.ContainsKey(clientUrl))
33. {
34. //注:Fleck中有释放
35. //关闭对象连接
36. //if (dic_Sockets[clientUrl] != null)
37. //{
38. //dic_Sockets[clientUrl].Close();
39. //}
40. dic_Sockets.Remove(clientUrl);
41. }
42. "|服务器:和客户端网页:" + clientUrl + " 断开WebSock连接!");
43. };
44. //接受客户端网页消息事件
45. {
46. string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
47. "|服务器:【收到】来客户端网页:" + clientUrl + "的信息:\n" + message);
48. };
49. });
50. 
51. Console.ReadKey();
52. foreach (var item in dic_Sockets.Values)
53. {
54. if (item.IsAvailable == true)
55. {
56. "服务器消息:" + DateTime.Now.ToString());
57. }
58. }
59. Console.ReadKey();
60. 
61. //关闭与客户端的所有的连接
62. foreach (var item in dic_Sockets.Values)
63. {
64. if (item != null)
65. {
66. item.Close();
67. }
68. }
69. 
70. Console.ReadKey();
71. }
72. }
73. }      

四. 结束语(Ending)

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

(2). 本文主要是用作记录成长历程的,还有这个WebSocket实践性比较强,所以还是要自己动手去试试。所以博客主由于在时间精力不是很的情况下就不去过多的强调代码了。如果真的需要可以下载我上面代码的原工程。最后我把Fleck的包也给一下吧。

​​工程源代码(环境vs2015)​​