TODO: 这篇文章只是写了一个 DEMO, 告诉你如何使用 C# 构建一个 webSocket 服务器, 以便 html 网页可以通过 WebSocket 与之进行交互.
将会使用到的 Package:
- websocket-sharp
- Newtonsoft.JSON
这个 DEMO 主要完成的工作是:
HTML 连接 WebSocket 并传送一个 JSON,JSON 包含两个数字 a 和 b.
服务器监听 WebSocket 并解析 JSON 里面的两个数字, 将两个数字加起来的和作为结果以 JSON 的形式传送给 HTML.
HTML 得到返回以后更新显示.
10 秒之后, 服务器主动向浏览器再发送一次消息.
准备姿势
新建工程
首先需要准备两个工程:
一个是 Web 项目, 可以是任何 Web 项目, 因为我们只用到 HTML.HTML 单文件也是没有问题的. 这里我用的是 vscode live server.
另一个是 C# 命令行项目, 当然也可以不是命令行, 只是觉得命令行比较方便, DEMO 也不需要窗体, 如果你需要窗体可以使用 WPF 或者 WinForms.
必要依赖
在 C# 项目中, 我们需要安装 Nuget 包: WebSocketSharp (由于这个 Nuget 包在写文的时候还是 rc, 所以需要勾选包括抢鲜版才会搜索出来哦) 和 Newtonsoft.JSON
服务器代码
首先我们需要新建一个类, 作为一个 App, 去处理传送来的消息.
- using Newtonsoft.JSON;
- using Newtonsoft.JSON.Linq;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using WebSocketSharp;
- using WebSocketSharp.Server;
- namespace WebSocketDemo
- {
- class Add : WebSocketBehavior
- {
- protected override void OnOpen()
- {
- Console.WriteLine("Connection Open");
- base.OnOpen();
- }
- protected override void OnMessage(MessageEventArgs e)
- {
- var data = e.Data;
- if (TestJson(data))
- {
- var param = JToken.Parse(data);
- if (param["a"] != null && param["b"] != null)
- {
- var a = param["a"].ToObject<int>();
- var b = param["b"].ToObject<int>();
- Send(JsonConvert.SerializeObject(new { code = 200, msg = "result is" + (a + b) }));
- Task.Factory.StartNew(() => {
- Task.Delay(10000).Wait();
- Send(JsonConvert.SerializeObject(new { code = 200, msg = "I just to tell you, the connection is different from http, i still alive and could send message to you." }));
- });
- }
- }
- else
- {
- Send(JsonConvert.SerializeObject(new { code = 400, msg = "request is not a json string." }));
- }
- }
- protected override void OnClose(CloseEventArgs e)
- {
- Console.WriteLine("Connection Closed");
- base.OnClose(e);
- }
- protected override void OnError(ErrorEventArgs e)
- {
- Console.WriteLine("Error:" + e.Message);
- base.OnError(e);
- }
- private static bool TestJson(string JSON)
- {
- try
- {
- JToken.Parse(JSON);
- return true;
- }
- catch (JsonReaderException ex)
- {
- Console.WriteLine(ex);
- return false;
- }
- }
- }
- }
上面这一段代码中, 重点在于 OnMessage 方法, 这个方法就是处理消息的主要流程.
在 Main 函数中, 我们加入下面的代码. 6690 是这次 Demo 使用的端口号, 第二行 AddWebSocketService 添加了一行路由, 使得连接到 ws://localhost:6690/add 可以导向我们预定义好的 App 类中的处理逻辑.
- using System;
- using WebSocketSharp.Server;
- namespace WebSocketDemo
- {
- class Program
- {
- static void Main(string[] args)
- {
- var wssv = new WebSocketServer(6690);
- wssv.AddWebSocketService<Add>("/add");
- wssv.Start();
- Console.WriteLine("Server starting, press any key to terminate the server.");
- Console.ReadKey(true);
- wssv.Stop();
- }
- }
- }
客户端代码
- <!DOCTYPE HTML>
- <HTML>
- <head>
- <meta charset="utf-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <title>
- WebSocket DEMO
- </title>
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <style>
- ul, li { padding: 0; margin: 0; list-style: none; }
- </style>
- </head>
- <body>
- <div>
- a:
- <input type="text" id="inpA" />
- b:
- <input type="text" id="inpB" />
- <button type="button" id="btnSub">
- submit
- </button>
- </div>
- <ul id="outCnt">
- </ul>
- <script>
- let wsc;
- var echo = function(text) {
- var echoone = function(text) {
- var dom = document.createElement("li");
- var t = document.createTextNode(text);
- dom.appendChild(t);
- var cnt = document.getElementById("outCnt");
- cnt.appendChild(dom);
- };
- if (Array.isArray(text)) {
- text.map(function(t) {
- echoone(t);
- });
- } else {
- echoone(text);
- }
- }; (function() {
- if ("WebSocket" in Windows) {
- // init the websocket client
- wsc = new WebSocket("ws://localhost:6690/add");
- wsc.onopen = function() {
- echo("connected");
- };
- wsc.onclose = function() {
- echo("closed");
- };
- wsc.onmessage = function(e) {
- var data = JSON.parse(e.data);
- echo(data.msg || e.data);
- console.log(data.msg || e.data);
- };
- // define click event for submit button
- document.getElementById("btnSub").addEventListener('click',
- function() {
- var a = parseInt(document.getElementById("inpA").value);
- var b = parseInt(document.getElementById("inpB").value);
- if (wsc.readyState == 1) {
- wsc.send(JSON.stringify({
- a: a,
- b: b
- }));
- } else {
- echo("service is not available");
- }
- });
- }
- })();
- </script>
- </body>
- </HTML>
当创建 WebSocket 对象的时候, 会自动进行连接, 这个对象可以用 onopen,onclose,onmessage 分别处理事件. 主要通讯的流程也是在 onmessage 中进行处理.
来源: https://segmentfault.com/a/1190000017180726