基於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 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM