您当前的位置 :首页 > 学习资料 > 在IIS上搭建WebSocket服务器
投稿

在IIS上搭建WebSocket服务器

2021-03-21 23:01:29 来源: 作者: 责任编辑:cncml

一、搭建环境
1.System.Web.WebSockets需搭建在Windows8及Server2012以上系统的上。
2.在Windows8及Server2012以上系统的上安装IIS和WebSocket。
1).我们在控制面板里打开“启用或关闭windows功能“
2)安装IIS和WebSocket协议
3.构建网站
打开IIS管理器,新建网站WebSocketHandler
4.打开“配置编辑器”
设置enable为true
 
 
 
 [!--empirenews.page--]在IIS上搭建WebSocket服务器(二)[/!--empirenews.page--]
 
服务器端代码编写
1.新建一个ASP.net Web MVC5项目
 
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.WebSockets;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using System.Web;
  9. using System.Web.WebSockets;
  10.  
  11.  
  12. namespace WebApplicationWebsocketHandler
  13. {
  14.     /// <summary>
  15.     /// 离线消息
  16.     /// </summary>
  17.     public class MessageInfo
  18.     {
  19.         public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)
  20.         {
  21.             MsgTime = _MsgTime;
  22.             MsgContent = _MsgContent;
  23.         }
  24.         public DateTime MsgTime { get; set; }
  25.         public ArraySegment<byte> MsgContent { get; set; }
  26.     }
  27.  
  28.  
  29.  
  30.  
  31.     /// <summary>
  32.     /// Handler1 的摘要说明
  33.     /// </summary>
  34.     public class Handler1 : IHttpHandler
  35.     {
  36.         private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池
  37.         private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池
  38.         public void ProcessRequest(HttpContext context)
  39.         {
  40.             //context.Response.ContentType = "text/plain";
  41.             //context.Response.Write("Hello World");
  42.             if (context.IsWebSocketRequest)
  43.             {
  44.                 context.AcceptWebSocketRequest(ProcessChat);
  45.             }
  46.         }
  47.  
  48.         private async Task ProcessChat(AspNetWebSocketContext context)
  49.         {
  50.             WebSocket socket = context.WebSocket;
  51.             string user = context.QueryString["user"].ToString();
  52.  
  53.             try
  54.             {
  55.                 #region 用户添加连接池
  56.                 //第一次open时,添加到连接池中
  57.                 if (!CONNECT_POOL.ContainsKey(user))
  58.                     CONNECT_POOL.Add(user, socket);//不存在,添加
  59.                 else
  60.                     if (socket != CONNECT_POOL[user])//当前对象不一致,更新
  61.                         CONNECT_POOL[user] = socket;
  62.                 #endregion
  63.  
  64.                 #region 离线消息处理
  65.                 if (MESSAGE_POOL.ContainsKey(user))
  66.                 {
  67.                     List<MessageInfo> msgs = MESSAGE_POOL[user];
  68.                     foreach (MessageInfo item in msgs)
  69.                     {
  70.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
  71.                     }
  72.                     MESSAGE_POOL.Remove(user);//移除离线消息
  73.                 }
  74.                 #endregion
  75.  
  76.                 string descUser = string.Empty;//目的用户
  77.                 while (true)
  78.                 {
  79.                     if (socket.State == WebSocketState.Open)
  80.                     {
  81.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
  82.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
  83.  
  84.                         #region 消息处理(字符截取、消息转发)
  85.                         try
  86.                         {
  87.                             #region 关闭Socket处理,删除连接池
  88.                             if (socket.State != WebSocketState.Open)//连接关闭
  89.                             {
  90.                                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池
  91.                                 break;
  92.                             }
  93.                             #endregion
  94.  
  95.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
  96.                             string[] msgList = userMsg.Split('|');
  97.                             if (msgList.Length == 2)
  98.                             {
  99.                                 if (msgList[0].Trim().Length > 0)
  100.                                     descUser = msgList[0].Trim();//记录消息目的用户
  101.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
  102.                             }
  103.                             else
  104.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
  105.  
  106.                             if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线
  107.                             {
  108.                                 WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端
  109.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)
  110.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
  111.                             }
  112.                             else
  113.                             {
  114.                                 Task.Run(() =>
  115.                                 {
  116.                                     if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中
  117.                                         MESSAGE_POOL.Add(descUser, new List<MessageInfo>());
  118.                                     MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
  119.                                 });
  120.                             }
  121.                         }
  122.                         catch (Exception exs)
  123.                         {
  124.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息
  125.                         }
  126.                         #endregion
  127.                     }
  128.                     else
  129.                     {
  130.                         break;
  131.                     }
  132.                 }//while end
  133.             }
  134.             catch (Exception ex)
  135.             {
  136.                 //整体异常处理
  137.                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);
  138.             }
  139.         }
  140.  
  141.  
  142.         public bool IsReusable
  143.         {
  144.             get
  145.             {
  146.                 return false;
  147.             }
  148.         }
  149.     }
  150. }
复制代码
4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径
 
 
 

[!--empirenews.page--]在IIS上搭建WebSocket服务器(三)[/!--empirenews.page--]
 
编写客户端代码
1.新建一个*.html文件。
ws = new WebSocket('ws://192.168.85.128:8086/Handler1.ashx?user=' + $("#user").val());
这个地方的IP和端口号对应着我们搭建在IIS上的WebSocket服务器
  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
  6.     <title></title>
  7.     <script src="http://code.jquery.com/jquery-1.4.1.min.js"></script>
  8.     <script>
  9.         var ws;
  10.         $().ready(function () {
  11.             $('#conn').click(function () {
  12.                 //ws = new WebSocket('ws://' + window.location.hostname + ':' + window.location.port + '/Handler1.ashx?user=' + $("#user").val());
  13.                 ws = new WebSocket('ws://192.168.85.128:8086/Handler1.ashx?user=' + $("#user").val());
  14.                 //var host = 'ws://192.168.85.128:8085/api/WSChat?user='+$("#user").val();
  15.                 //var host = "ws://192.168.85.128:8085/api/WSChat";
  16.                 //webSocket = new WebSocket(host);
  17.                
  18.                 $('#msg').append('<p>正在连接</p>');
  19.  
  20.                 ws.onopen = function () {
  21.                     $('#msg').append('<p>已经连接</p>');
  22.                 }
  23.                 ws.onmessage = function (evt) {
  24.                     $('#msg').append('<p>' + evt.data + '</p>');
  25.                 }
  26.                 ws.onerror = function (evt) {
  27.                     $('#msg').append('<p>' + JSON.stringify(evt) + '</p>');
  28.                 }
  29.                 ws.onclose = function () {
  30.                     $('#msg').append('<p>已经关闭</p>');
  31.                 }
  32.             });
  33.  
  34.             $('#close').click(function () {
  35.                 ws.close();
  36.             });
  37.  
  38.             $('#send').click(function () {
  39.                 if (ws.readyState == WebSocket.OPEN) {
  40.                     ws.send($("#to").val() + "|" + $('#content').val());
  41.                 }
  42.                 else {
  43.                     $('#tips').text('连接已经关闭');
  44.                 }
  45.             });
  46.  
  47.         });
  48.     </script>
  49. </head>
  50. <body>
  51.     <div>
  52.         <input id="user" type="text" />
  53.         <input id="conn" type="button" value="连接" />
  54.         <input id="close" type="button"  value="关闭"/><br />
  55.         <span id="tips"></span>
  56.         <input id="content" type="text" />
  57.         <input id="send" type="button"  value="发送"/><br />
  58.         <input id="to" type="text" />目的用户
  59.         <div id="msg">
  60.         </div>
  61.     </div>
  62. </body>
  63. </html>
复制代码
2.客户端A和客户端B通信效果
在浏览器中分别打开两个窗口,左边为客户端A,右边为客户端B,点击“连接”按钮,AB客户端分别与服务器建立连接
填写要发送的内容,即可看到A和B互相发送的信息了,即实现了AB客户端实现了WebSocket即时通信。
 
 
 



 
文章来源: 责任编辑:cncml
版权声明:
1、本主题所有言论和图片纯属会员个人意见,与本网站立场无关
2、本站所有主题由该文章作者发表,该文章作者与享有文章相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和的同意
4、文章作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、管理员和版主有权不事先通知发贴者而删除本文
不良信息举报信箱 新闻热线:18733599993 技术服务:18733599993 网上投稿
关于本站 | 广告服务 | 免责申明 | 招聘信息 | 联系我们
在线网 版权所有 Copyright(C)2005-2025