出售域名 11365.com.cn
有需要请联系 16826375@qq.com
在手机上浏览
在手机上浏览

WebSocket .net使用方法

发布日期:2023-05-10

WebSocket不能像TCP的Socket那样直连,需要通过服务端中转。

那么首先我们创建一个windows服务,开启后网页只要连接即可。

 

一、WebSocket服务端

using System;
using System.Collections.Generic;
using Fleck;
using log4net;
using Topshelf;

namespace com.CTT.WebSocketService
{
    public class WebSocketHandler
    {
        readonly ILog log = LogManager.GetLogger("WebSocketService");
        WebSocketServer server = new WebSocketServer(System.Configuration.ConfigurationManager.AppSettings["server_url"])
        {
            RestartAfterListenError = true //出错后进行重启
        };

        //记录所有连接的客户端
        IDictionary<string, IWebSocketConnection> dictSockets = new Dictionary<string, IWebSocketConnection>();

        public WebSocketHandler()
        {
            //开始监听
            server.Start(socket =>
            {
                socket.OnOpen = () =>   //连接建立事件
                {
                    //获取客户端网页的url
                    var clientUrl = socket.ConnectionInfo.ClientIpAddress   ":"   socket.ConnectionInfo.ClientPort;
                    if (!dictSockets.ContainsKey(clientUrl))
                    {
                        dictSockets.Add(clientUrl, socket);
                        log.Info("和客户端网页:"   clientUrl   " 建立WebSock连接");
                    }
                };
                socket.OnClose = () =>  //连接关闭事件
                {
                    var clientUrl = socket.ConnectionInfo.ClientIpAddress   ":"   socket.ConnectionInfo.ClientPort;
                    //如果存在这个客户端,那么对这个socket进行移除
                    if (dictSockets.ContainsKey(clientUrl))
                        dictSockets.Remove(clientUrl);

                    log.Info("和客户端网页:"   clientUrl   " 断开WebSock连接");
                };
                socket.OnMessage = message =>  //接受客户端网页消息事件
                {
                    var clientUrl = socket.ConnectionInfo.ClientIpAddress   ":"   socket.ConnectionInfo.ClientPort;
                    if (dictSockets != null && dictSockets.Count > 0)
                    {
                        foreach (var item in dictSockets.Values)
                            item.Send(message); //给所有连接的客户端广播
                    }

                    log.Info("收到"   clientUrl   "的消息,并广播消息:"   message);
                };
            });
        }

        public void Start()
        {
            log.Info("启用服务");
        }
        public void Stop()
        {
            if (dictSockets != null && dictSockets.Count > 0)
            {
                foreach (var item in dictSockets.Values)
                    item.Close(); //关闭所有的连接
            }

            log.Info("关闭服务");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //var logCfg = new FileInfo(AppDomain.CurrentDomain.BaseDirectory   "log4net.config");
            //XmlConfigurator.ConfigureAndWatch(logCfg);

            var rc = HostFactory.Run(x =>                                   //1
            {
                x.Service<WebSocketHandler>(s =>                                   //2
                {
                    s.ConstructUsing(name => new WebSocketHandler());                //3
                    s.WhenStarted(tc => tc.Start());                         //4
                    s.WhenStopped(tc => tc.Stop());                          //5
                });
                x.RunAsLocalSystem();                                       //6

                x.SetDescription("先配置server_url,网页的websocket指向此地址,实现实时通讯");                   //服务描述
                x.SetDisplayName("WebSocket服务端");                                  //服务显示名称
                x.SetServiceName("com.CTT.WebSocketService");                                  //服务名称
            });                                                             //10

            var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode());  //11
            Environment.ExitCode = exitCode;
        }
    }
}

注意:在app.config里配置服务端地址server_url:ws://192.168.0.211:8181

这里使用了Fleck框架,他会自动生成WebSocket的服务器,Fleck是开源的组件,开源地址是:https://github.com/statianzo/Fleck

生成Release版本,并生成服务

打开cmd,cd到文件所在目录,执行以下命令(注意:必须要管理员权限,不然安装不成功

com.CTT.WebSocketService Install //安装
com.CTT.WebSocketService Start //启动
com.CTT.WebSocketService Stop //停止
com.CTT.WebSocketService UnInstall //卸载服务

 

二、网页客户端

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .message{
            width: 60%;
            margin: 0 10px;
            display: inline-block;
            text-align: center;
            height: 40px;
            line-height: 40px;
            font-size: 20px;
            border-radius: 5px;
            border: 1px solid #B3D33F;
        }
        .form{
            width:100%;
            position: fixed;
            bottom: 300px;
            left: 0;
        }
        .connect{
            height: 40px;
            vertical-align: top;
            /* padding: 0; */
            width: 80px;
            font-size: 20px;
            border-radius: 5px;
            border: none;
            background: #B3D33F;
            color: #fff;
        }
    </style>
</head>
<body onload="connectWebSocket();">
<ul id="content"></ul>
<form class="form">
<input type="text" placeholder="请输入发送的消息" class="message" id="message"/>
<input type="button" value="发送" id="send" class="connect"/>
</form>
</body>
</html>
<script>
    var ws=null;
    var oUl=document.getElementById('content');
    var oSend=document.getElementById('send');
    var oInput=document.getElementById('message');   

    var connectWebSocket=function(){
        ws=new WebSocket('ws://192.168.0.211:8181');
        ws.onopen=function(){
            oUl.innerHTML ="<li>客户端已连接</li>";
        }
        ws.onmessage=function(evt){
            oUl.innerHTML ="<li>" evt.data "</li>";
        }
        ws.onclose=function(){
            oUl.innerHTML ="<li>客户端已断开连接</li>";
        };
        ws.onerror=function(evt){
            oUl.innerHTML ="<li>" evt.data "</li>";
        };
    }     
    
    oSend.onclick=function(){
        if(ws){
            ws.send(oInput.value);
        }
    }
</script>

打开网页,立即连接上了服务端。

尝试创建2个相同的网站客户端,在其中一个网站发送消息,另一个也能收到。

 

点击下载源码

服务器下载

客户端下载