首页 > 编程语言 >使用JS和C#完成websocket双向通讯

使用JS和C#完成websocket双向通讯

时间:2023-12-17 18:34:11浏览次数:37  
标签:websocket C# app await JS ws using WebSocket public

写在前面:

微软官方对websocket的直接支持很差,教程也写得不用心。还要用户自己去转字节数组和字符串,太过分了!

毕竟主推SignalR。

本文是在官方教程的基础上,对其进行了一些简单的讲解,和方法提取、封装,以期降低学习难度。


步骤描述:

1、随便建了个普通的mvc项目(任意带控制器的.net项目道理相同,都应该可以)。在Program.cs中,添加websocket支持。见以下代码第24行。

 

 1 namespace WebApplication2
 2 {
 3     public class Program
 4     {
 5         public static void Main(string[] args)
 6         {
 7             var builder = WebApplication.CreateBuilder(args);
 8 
 9             // Add services to the container.
10             builder.Services.AddControllersWithViews();
11 
12             var app = builder.Build();
13 
14             // Configure the HTTP request pipeline.
15             if (!app.Environment.IsDevelopment())
16             {
17                 app.UseExceptionHandler("/Home/Error");
18             }
19             app.UseStaticFiles();
20 
21             app.UseRouting();
22 
23             //启用websocket
24             app.UseWebSockets();
25             //app.UseAuthorization();
26 
27             app.MapControllerRoute(
28                 name: "default",
29                 pattern: "{controller=Home}/{action=Index}/{id?}");
30 
31             app.Run();
32         }
33     }
34 }

只支持ws或wss请求。

2、控制器代码如下。14行注册路由(即要以类似 ws://xxxx/ws 的方式访问)

 1 using Microsoft.AspNetCore.Http;
 2 using Microsoft.AspNetCore.Mvc;
 3 using System.Net.WebSockets;
 4 using System.Text;
 5 using WebApplication2.Function;
 6 
 7 namespace WebApplication2.Controllers
 8 {
 9     //[Route("api/[controller]")]
10     //[ApiController]
11     public class WebSocketController : ControllerBase
12     {
13         //注册路由
14         [Route("/ws")]
15         public async Task Get()
16         {
17             //如果是websocket请求
18             if (HttpContext.WebSockets.IsWebSocketRequest)
19             {
20                 //获得连接
21                 using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
22                 //处理程序
23                 await 处理程序(webSocket);
24             }
25             else
26             {
27                 HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
28             }
29         }
30 
31         async Task 处理程序(WebSocket w)
32         {
33             string s;
34             bool f;
35             //简单的处理,收消息,修改,发送。
36             (f,s)=await WebSocket操作.收(w);
37             while(f)
38             {
39                 s = "server:" + s;
40                 await WebSocket操作.发(w, s);
41                 (f,s)= await WebSocket操作.收(w);
42             }
43             await WebSocket操作.关(w);
44         }
45     }
46 }

注释都比较清楚,不赘述。

31行开始的处理程序,从设计的角度,不应该出现在控制器里。介意的读者,请自行处理。

WebSocket操作类,见后面。

3、WebSocket操作类:

 1 using System;
 2 using System.Net.WebSockets;
 3 using System.Text;
 4 
 5 namespace WebApplication2.Function
 6 {
 7     //对微软官方示例的简单封装,
 8     public class WebSocket操作
 9     {
10         //接收消息,bool指示收到的是不是关闭消息,string是收到的内容。
11         public static async Task<(bool,string)> 收(WebSocket ws)
12         {
13             //接收大小最多4k。
14             var buffer = new byte[1024 * 4];
15             string s;
16             //把消息收到字节数组中
17             var receiveResult = await ws.ReceiveAsync(
18                 new ArraySegment<byte>(buffer), CancellationToken.None);
19             //如果不是关闭消息
20             if (!receiveResult.CloseStatus.HasValue)
21             {
22                 //转换为字符串返回
23                 s = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count);
24                 return (true,s);
25             }
26             else
27             {
28                 s = "无";
29                 return (false,s);
30             }
31         }
32 
33         //发送消息
34         public static async Task 发(WebSocket ws, string s)
35         {
36             //消息转换成字节数组
37             var buffer = Encoding.UTF8.GetBytes(s);
38             //发送
39             await ws.SendAsync(
40                 new ArraySegment<byte>(buffer, 0, buffer.Length),
41                 WebSocketMessageType.Text,
42                 true,
43                 CancellationToken.None);
44         }
45         public static async Task 关(WebSocket ws)
46         {
47             //官方例子里,status是接收到的关闭类型。这里偷懒,应该也不影响用。
48             var status = ws.CloseStatus == null ? WebSocketCloseStatus.Empty :ws.CloseStatus.Value;
49             //关闭
50             await ws.CloseAsync(
51                 status,
52                 ws.CloseStatusDescription,
53                 CancellationToken.None);
54         }
55     }
56 }

 其中17-20,39-44,50-53行的代码,基本来自官方例程。我不求甚解,大家随意。

至此,服务端完成。


客户端,可以完全照搬 使用js和nodejs完成websocket双向通讯 里的web客户端。

运行结果:

 成功,调试通过。

 

标签:websocket,C#,app,await,JS,ws,using,WebSocket,public
From: https://www.cnblogs.com/wanjinliu/p/17909477.html

相关文章

  • js实现以鼠标为中心缩放图片
    直接上代码,不解释<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</tit......
  • 无涯教程-Java - toCharArray()函数
    此方法将此字符串转换为新的字符数组。char[]toCharArray()-语法这是此方法的语法-publicchar[]toCharArray()char[]toCharArray()-返回值它返回一个新分配的字符数组,其长度是此字符串的长度,并且其内容已初始化为包含此字符串表示的字符序列。char[]toCharArray()......
  • Scrum(七)
    一、各成员今日完成的任务邹雪梅完善用户管理和角色管理的界面原型。杨云泰调整密钥管理和公文传输前端页面王艺达完善数据库。李天赐完善加密算法的问题。魏子俊修改后端框架。二、各成员明日任务已无明日,但还差代码调试,与修改。邹雪梅调试修改角色管理的界面。杨......
  • USACO 2023-2024 赛季复盘
    【USACO23DEC】Cu复盘我先用了一个号打,然后是T1TLE*4,T2AC,T3WA*2。然后后面开了一个号调了一些,喜提阿克。T1:首先我们知道,对于\(a_1\)每一次是最先吃糖果的。所以必然有两个情况:全部给他吃了吃了一些首先情况一,我们可以直接特判掉。剩下情况二,吃了一些没吃完......
  • ExeIconToFolder 提取exe程序图标,并设置exe所在文件夹图标
    ExeIconToFolder提取exe程序图标,并设置exe所在文件夹图标2023年12月17日提取exe程序图标,并设置exe所在文件夹图标所需第三方程序IconsExtract-EXE图标提取(nirsoft.net)RestartExplorer---重新启动资源管理器(sordum.org)代码@echooffsetlocalenabledelayed......
  • JavaScript调研
    一、JS初识1、JavaScript一种直译式脚本语言;2、组成部分;(1)ECMAScript语法和基本对象(2)文档对象模型(DOM)处理网页内容的方法和接口(3)浏览器对象模型(BOM)与浏览器进行交互的方法和接口3、JS特点(1)解释性脚本语言(2)用来向HTML页面添加交互行为,可以嵌入HTML......
  • 记Linux跑ChatGLM2的坑及低显存解决办法
    记录一下踩过的坑…0.环境配置:全程国内网Ubuntu20.04withPython3.8andCUDA12.2RTX3060Laptop(6G)1.ChatGLM的下载:#clone仓库gitclonehttps://gitclone.com/github.com/THUDM/ChatGLM2-6BcdChatGLM2-6Bpip3install-rrequirements.txt#pip加速自行百......
  • 和鲸科技CEO范向伟受邀出席港航数据要素流通与生态合作研讨会,谈数据资产入表的战略机
    近日,由上海虹口数字航运创新中心、龙船(北京)科技有限公司(下简称“龙船科技”)、华东江苏大数据交易中心联合举办的“港航数据要素流通与生态合作研讨会”圆满落幕,来自港航领域的近百名企业代表共同参与。上海和今信息科技有限公司(简称“和鲸科技”)的创始人、CEO范向伟,受龙船科技邀请......
  • uniapp Watch() 数据监控完成升级
    handleDataChange(){ if(this.allquestions<50){ this.rank=1 this.rankpic='https://imgs.91yuwen.com/resouse/%E5%BE%BD%E7%AB%A0/11.png' this.rankrate=Number(this.allquestions)/50*100 console.log('进入1�......
  • C#中的数据库访问类DBHelper
    1、在配置文件中添加连接字符串首先在配置文件中的<configuration>中加入数据库连接字符串,配置文件后缀为.config,例如:App.config<connectionStrings><addname="你给此条链接起的名字,随便起,访问的时候可以用。比如:AAA"connectionString="DataSource=你的服务器地址;Init......