记一下在IIS中部署WebSocket服务的经验
因业务需求需要使用长连接推送数据,这边选择使用.NET框架原生支持的WebSocket技术。
一、版本要求
- 对于IIS的版本必须是 IIS 8.0 及以上
- .NET Framework版本必须为 4.5 及以上
PS:低于上述版本,需要自己实现协议或寻找第三方实现
二、IIS配置
- 在服务器IIS上安装“WebSocket 协议”服务,参考微软官方教程
- 在Web站点中的站点配置里启用Websocket支持,参考教程
- 选择一个站点或应用程序
- 找到配置编辑器
- 选择节点system.webServer/webSocket
- 设置enabled为true
三、测试代码
using System; using System.Collections.Generic; using System.Linq; using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; using System.Web; using System.Web.WebSockets; namespace SimpleWebSocket { /// <summary> /// /// </summary> public class WebSocketHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { //检查 查询是否是WebSocket请求 if (HttpContext.Current.IsWebSocketRequest) { //如果是,我们附加异步处理程序 context.AcceptWebSocketRequest(WebSocketRequestHandler); } } public bool IsReusable { get { return false; } } //异步请求处理程序 public async Task WebSocketRequestHandler(AspNetWebSocketContext webSocketContext) { //获取当前的WebSocket对象 WebSocket webSocket = webSocketContext.WebSocket; /* * 我们定义一个常数,它将表示接收到的数据的大小。 它是由我们建立的,我们可以设定任何值。 我们知道在这种情况下,发送的数据的大小非常小。 */ const int maxMessageSize = 1024; //received bits的缓冲区 var receivedDataBuffer = new ArraySegment<Byte>(new Byte[maxMessageSize]); var cancellationToken = new CancellationToken(); //检查WebSocket状态 while (webSocket.State == WebSocketState.Open) { //读取数据 WebSocketReceiveResult webSocketReceiveResult = await webSocket.ReceiveAsync(receivedDataBuffer, cancellationToken); //如果输入帧为取消帧,发送close命令 if (webSocketReceiveResult.MessageType == WebSocketMessageType.Close) { await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, cancellationToken); } else { byte[] payloadData = receivedDataBuffer.Array.Where(b => b != 0).ToArray(); //因为我们知道这是一个字符串,我们转换它 string receiveString = System.Text.Encoding.UTF8.GetString(payloadData, 0, payloadData.Length); //将字符串转换为字节数组. var newString = String.Format("Hello, " + receiveString + " ! Time {0}", DateTime.Now.ToString()); Byte[] bytes = System.Text.Encoding.UTF8.GetBytes(newString); //发回数据 await webSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, cancellationToken); } } } } }
四、项目配置
在项目的Web.config文件里确保如下配置正确:
<configuration> <system.web> <httpRuntime targetFramework="4.5" /> </system.web> </configuration>
主要是“<httpRuntime targetFramework="4.5" />”这行配置,一定要4.5及以上版本。
PS:如果有 httpRuntime 这个节点了,则加上 targetFramework="4.5" 即可
然后将项目部署到IIS上
其他问题
一、配置都没问题,本地测试也没问题,但线上WebSocket就是连不上,且无任何报错,仿佛被什么拦截了
检查一下IIS里部署的目标站点其开放的端口,是否只开放了443端口,即https。此时用wss协议连接试试,如“wss://127.0.0.1/test.ashx”
PS:因为网站出于安全考虑,一般不使用未加密的http协议,即80端口。而ws协议连接的正是80端口,就被拦截了。使用wss协议会连接443端口,就正常了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?