• 基于WebSocketSharp 的IM 简单实现


    websocket-sharp 是一个websocket的C#实现,支持.net 3.5及以上来开发服务端或者客户端。本文主要介绍用websocket-sharp来做服务端、JavaScript做客户端来实现一个简单的IM。

    WebSocketBehavior

    WebSocketBehavior是核心对象,他包含了OnOpen,OnMessage,OnClose,OnError四个方法以及一个Sessions对象。熟悉websocket的都知道前四个方法是用来处理客户端链接、发送消息、链接关闭以及出错。sessions就是用来管理所有的回话连接。每产生一个连接,都会有一个新Id,sessions中会新增一个IWebSocketSession对象。当页面关闭或者刷新都会触发OnClose,继而sessions中会移除对应的IwebSocketSession对象。

    WebSocketSessionManager 有一个广播方法:Sessions.Broadcast,通知所有连接的客户端。而WebSocketBehavior中的Send相当于是单发,只能将消息发送到此刻连接的一个客户端。摸清了以上这些我们就可以做一个简单的IM了。

    Websoket.Server

    新建一个C#控制台程序。现在Nugget中添加websocket-sharp.已经JSON。

    然后新增一个Chat类,继承WebSocketBehavior,Chat相当于是一个websocket的服务,你可以创建多个websocketBehavior的实例然后在挂载在websocketServer上。

     public class Chat : WebSocketBehavior
        {
            private  Dictionary<string,string> nameList=new Dictionary<string, string>();
            protected override async Task OnMessage(MessageEventArgs e)
            {
    
                StreamReader reader = new StreamReader(e.Data);
                string text = reader.ReadToEnd();
                try
                {
                    var obj = Json.JsonParser.Deserialize<JsonDto>(text);
                    Console.WriteLine("收到消息:" + obj.content + " 类型:" + obj.type + " id:" + Id);
                    switch (obj.type)
                    {
                        //正常聊天
                        case "1":
                            obj.name = nameList[Id];
                            await Sessions.Broadcast(Json.JsonParser.Serialize(obj));
                            break;
                        //修改名称
                        case "2":
                            Console.WriteLine("{0}修改名称{1}",nameList[Id],obj.content);
                            Broadcast(string.Format("{0}修改名称{1}", nameList[Id], obj.content),"3");
                            nameList[Id] = obj.content;
                            break;
                        default:
                            await Sessions.Broadcast(text);
                            break;
    
                    }
                }
                catch (Exception exception)
                {
                    Console.WriteLine(exception);
                }
              
                //await Send(text);
            }
            protected override async Task OnClose(CloseEventArgs e)
            {
                Console.WriteLine("连接关闭" + Id);
                Broadcast(string.Format("{0}下线,共有{1}人在线", nameList[Id], Sessions.Count), "3");
                nameList.Remove(Id);
            }
    
            protected override async Task OnError(WebSocketSharp.ErrorEventArgs e) 
            {
                var el = e;
            }
    
            protected override async Task OnOpen()
            {
                Console.WriteLine("建立连接"+Id);
                nameList.Add(Id,"游客"+Sessions.Count);
                Broadcast(string.Format("{0}上线了,共有{1}人在线", nameList[Id],Sessions.Count), "3");
    
            }
    
            private void Broadcast(string msg, string type = "1")
            {
                var data= new  JsonDto(){content = msg,type = type,name = nameList[Id]};
                Sessions.Broadcast(Json.JsonParser.Serialize(data));
            }
    
    
        }

    JsonDto

        class JsonDto
        {
            public string content { get; set; }
            public string type { get; set; }
            public string name { get; set; }
        }
    View Code

    这里用nameList来管理所有的链接Id和用户名称的对应关系,新上线的人都默认为游客。然后再OnMessage中定义了三种消息类型。1表示正常聊天,2表示修改名称。3表示系统通知。用来让前端做一些界面上的区分。

    然后在Program中启动WebSocketServer。下面指定了8080端口。

      public class Program
        {
            public static void Main(string[] args)
            {
                var wssv = new WebSocketServer(null,8080);
                wssv.AddWebSocketService<Chat>("/Chat");
                wssv.Start();
                Console.ReadKey(true);
                wssv.Stop();
            }
        }

    Client

    html:

     <div id="messages">
        </div>
       <input type="text" id="content" value=""/>
       <button id="sendbt">发送</button>
       <div>昵称:<input type="text" id="nickName"  /> <button id="changebt">修改</button> </div>
    View Code

    js:

     function initWS() {
            ws = new WebSocket("ws://127.0.0.1:8080/Chat");
            ws.onopen = function (e) {
                console.log("Openened connection to websocket");
                console.log(e);
            };
            ws.onclose = function () {
                console.log("Close connection to websocket");
                // 断线重连
                initWS();
            }
    
            ws.onmessage = function (e) {
                console.log("收到",e.data)
                var div=$("<div>");
                var data=JSON.parse(e.data);
                switch(data.type){
                    case "1":
                 div.html(data.name+":"+data.content);
                break;
                    case "2":
                    div.addClass("gray");
                    div.html("修改名称"+data.content)
                    break;
                    case "3":
                    div.addClass("gray");
                    div.html(data.content)
                    break;
                }
                $("#messages").append(div);
            }
        }
        
        initWS();
        function sendMsg(msg,type){
            ws.send(JSON.stringify({content:msg,type:type}));
        }
        $("#sendbt").click(function(){
           var text=$("#content").val();
           sendMsg(text,"1")
           $("#content").val("");
        })
        $("#changebt").click(function(){
            var text=$("#nickName").val();
            sendMsg(text,"2")
        })

    运行效果:

    是不是很方便~~,喜欢就赞一个。

    源码:https://files.cnblogs.com/files/stoneniqiu/websocket-sharp.zip

    websocket-sharp:http://sta.github.io/websocket-sharp/

    nodejs 实现websocket服务端:http://www.cnblogs.com/stoneniqiu/p/5402311.html 

  • 相关阅读:
    jQuery选择器大全(48个代码片段+21幅图演示)
    抽象和模型
    什么叫做精通,我来给大家解释一下
    设置浏览器固定大小的固定位置的方法
    selenium对浏览器属性操作的方法
    selenium 最大化浏览器是解决浏览器和驱动不匹配的方法如下
    java selenium手动最大化chrome浏览器的方法
    java selenium启动火狐浏览器报错:Cannot find firefox binary in PATH. Make sure firefox is installed. OS appears to be: VISTA Build info: version: '3.8.1', revision: '6e95a6684b', time: '2017-12-01T19:05:14.666Z
    mygenerator().next() AttributeError: 'generator' object has no attribute 'next'
    马的遍历 搜索
  • 原文地址:https://www.cnblogs.com/stoneniqiu/p/8488150.html
Copyright © 2020-2023  润新知