欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

asp.net网站作为websocket服务端的应用该如何写

程序员文章站 2023-10-27 18:11:52
最近被websocket的一个问题困扰了很久,有一个需求是在web网站中搭建websocket服务。客户端通过网页与服务器建立连接,然后服务器根据ip给客户端网页发送信息。 其实,这个需求并不难,只是刚开始对websocket的内容不太了解。上网搜索了一下,有通过asp.net core 实现的、有 ......

  最近被websocket的一个问题困扰了很久,有一个需求是在web网站中搭建websocket服务。客户端通过网页与服务器建立连接,然后服务器根据ip给客户端网页发送信息。

  其实,这个需求并不难,只是刚开始对websocket的内容不太了解。上网搜索了一下,有通过asp.net core 实现的、有通过一般处理程序ashx文件来实现的,这些方法不能满足我当前网站的需求。我自己通过signalr也实现了此功能,而且使用signalr实现起来会更简单。但是我的需求是客户端不是我编写,而且是一个手持机,只给我留了一个填写websocket服务器地址的地方,所以我没有办法通过signalr封装的js去调用后台的websocket服务。如果你的需求不像我这么苛刻,你完全可以通过signalr实现,而且更加简单。

  最后,通过fleck第三方库实现了我想要的功能。下面详细说一下我的实现过程。

  1.下载fleck第三方库,我是通过git下载的,源码下载

   点击页面中的clone or download -> download zip,下载

   asp.net网站作为websocket服务端的应用该如何写

  下载完之后,可以查看里面的文档,具体的实现可以查看代码。

 

  2.将fleck加入到自己的项目中,并对fleck进行引用。

  asp.net网站作为websocket服务端的应用该如何写

 

  3.编写我们自己的websocket类

using system;
using system.collections.generic;
using system.configuration;
using system.linq;
using system.web;
using fleck;

namespace faw.common
{
    public class wscontext
    {
        //客户端url以及其对应的socket对象字典
        static idictionary<string, iwebsocketconnection> dic_sockets = new dictionary<string, iwebsocketconnection>();

        public static void startupws()
        {
            string ipvalue = configurationmanager.appsettings["websocketaddress"];
            //创建
            //websocketserver server = new websocketserver("ws://127.0.0.1:8819/terver");//监听所有的的地址
            websocketserver server = new websocketserver(ipvalue);//监听的地址写在配置文件里
            //出错后进行重启
            server.restartafterlistenerror = true;

            //开始监听
            server.start(socket =>
            {
                socket.onopen = () =>   //连接建立事件
                {
                    //获取客户端网页的url
                    string clienturl = socket.connectioninfo.clientipaddress + ":" + socket.connectioninfo.clientport;
                    dic_sockets.add(clienturl, socket);
                    logmanager.writelog("服务器:和客户端网页:[" + clienturl + "] 建立websock连接!");
                };
                socket.onclose = () =>  //连接关闭事件
                {
                    string clienturl = socket.connectioninfo.clientipaddress + ":" + socket.connectioninfo.clientport;
                    //如果存在这个客户端,那么对这个socket进行移除
                    if (dic_sockets.containskey(clienturl))
                    {
                        //注:fleck中有释放
                        //关闭对象连接 
                        if (dic_sockets[clienturl] != null)
                        {
                            dic_sockets[clienturl].close();
                        }
                        dic_sockets.remove(clienturl);
                    }
                    logmanager.writelog("服务器:和客户端网页:[" + clienturl + "]  断开websock连接!");
                };
                socket.onmessage = message =>  //接受客户端网页消息事件
                {
                    string clienturl = socket.connectioninfo.clientipaddress + ":" + socket.connectioninfo.clientport;
                    logmanager.writelog("服务器:【收到】来客户端网页:" + clienturl + "的信息:\n" + message);

                };
            });

        }

        public static void sendmsg(string ipaddress, string jsonstring)
        {
            if (string.isnullorempty(jsonstring))
            {
                //写日志
                logmanager.writelog("中止发送,向客户端发送信息为空。" );
                return;
            }
            foreach (var item in dic_sockets.values)
            {
                if (item.isavailable == true && item.connectioninfo.clientipaddress == ipaddress)
                {
                    logmanager.writelog("服务器: 向客户端发送信息为 " + jsonstring);
                    item.send(jsonstring);
                }
            }
        }
    }
}

 

  这段代码呢,startupws函数主要是建立一个websocket服务端,sendmsg函数是负责提供外部调用向指定的客户端发送内容的工作。

            try
            {
                string pdaip = cameralogic.querypdaipbyip(cameraip);
                logmanager.writelog("获取摄像头对应的手机机ip:" + pdaip);
                wscontext.sendmsg(pdaip, sendmessage);
            }
            catch (exception ex)
            {
                logmanager.writelog("手动抬杆websocket异常:" + ex.message);
            }            

  这个代码片段就是在网站中调用sendmsg函数,给指定的客户端发送数据。

  注意:这里要提一点,如果websocket服务的端口要提供给外网访问的话,需要将端口加入到防火墙入站规则中,并且需要做一下内外网ip和端口的映射,否则外网想访问这个服务是不可以的。

  4.接下来我们就要将websocket添加到网站中,让它随着网站的启动而启动。

using system;
using system.collections.generic;
using system.linq;
using system.web;
using system.web.routing;
using system.web.security;
using faw.web;
using faw.common;

namespace faw.web
{
    public class global : httpapplication
    {
        void application_start(object sender, eventargs e)
        {
            // 在应用程序启动时运行的代码
            authconfig.registeropenauth();

            //建立websocket服务器
            wscontext.startupws();
        }
        
    }
}

   这样就可以了。

  5.测试websocket服务是否可用的话,可以通过websocket在线测试的功能。这个只要百度一下,你就全知道了,很简单,这里不再介绍。

  总结:其实websocket的操作真的不难,就是普通的http请求得到了一次升级后,建立了一个全双工的通道,可以相互发送信息。只是我在网上并没有找到asp.net网站作为服务端的例子,其实需要做的只有两步:1.建立一个websocket的服务端;2.将websocket的服务端加入到global文件中,随程序一起启动。我把这个分享出来,希望可以帮助更多的人。