iT邦幫忙

0

C# WebSocket實作雙向通訊

本文將透過WebSocketSharp來實作WebSocket

Client使用js
Server使用C# .net 4.6.2

Step 1 下載NuGet套件
工具->NuGet套件管理員->管理方案的NuGet套件
https://ithelp.ithome.com.tw/upload/images/20210512/20110063oy9iCSA6ZG.png

Step2 撰寫Server程式
(1) Global.設定監聽port與連線Url
new WebSocketServer()可以設定監聽port與Url、加密連線

public class WebApiApplication : HttpApplication
{
    public static WebSocketServer WebSocketServer { get; private set; }

    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);

        WebSocketServer = new WebSocketServer(5000);
        WebSocketServer.AddWebSocketService<NotifyBehavior>("/notify");
        WebSocketServer.Start();
    }
}

(2) 新增Behavior

public class NotifyBehavior : WebSocketBehavior
{
    protected override void OnOpen()
    {
        //傳送訊息至Client
        Send(JsonConvert.SerializeObject(new { message = "Open" }));
    }

    protected override void OnMessage(MessageEventArgs e)
    {
        //接收Client傳入的訊息
        string msg = e.Data;
    }

    protected override void OnClose(CloseEventArgs e)
    {
        
    }

    protected override void OnError(ErrorEventArgs e)
    {
        
    }
}

Step 3 撰寫Client程式

 <script>
        let wsc;
        (function () {
            if ("WebSocket" in window) {
                wsc = new WebSocket("ws://localhost:5000/notify");

                wsc.onopen = function () {
                    console.log("connected");
                    //傳送訊息至Server
                    wsc.send('Client Connected.');
                };
                wsc.onclose = function () {
                    console.log("closed");
                };
                wsc.onmessage = function (e) {
                    //接收Server傳入的訊息
                    var data = JSON.parse(e.data);
                    console.log(data.message);
                };
            }
        })();
    </script>

Step 4 Demo
Client可接收Server傳送的訊息"Open"
https://ithelp.ithome.com.tw/upload/images/20210613/20110063ZWvKiUDvoR.png
Server可接收Client傳送的訊息"Client Connected."
https://ithelp.ithome.com.tw/upload/images/20210613/20110063qpIHLEAEYl.png

程式碼: https://github.com/jing-yu-wang/WebSocket


同場加映 使用wss連接
Server
path、pwd放站台憑證的路徑與密碼

WebSocketServer = new WebSocketServer(5000), true);
WebSocketServer.SslConfiguration.ServerCertificate = new X509Certificate2(path, pwd);

Client
將ws改為wss即可

wsc = new WebSocket("wss://localhost:5000/notify");

使用wss連線時遇到Client無法連線至Server的狀況
failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
後來發現是要指定Tls1.2 連線

WebSocketServer.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12;

遇到的問題
站台回收後無法連線
將WebSocket Server架在IIS站台,站台回收後要將應用程式集區重新喚醒,才可以重新連線
(Web API、MVC網站架在IIS不會遇到這個問題,因為在第一個連線進來Request會自動將應用程式集區喚醒)

目前的解法:

  1. 設定Windows排程,每日固定時間執行以下cmd指令喚醒站台

powershell -Command "Invoke-WebRequest {站台Url} "

  1. WebSocket Server安裝在Windows Service(尚未嘗試)
    這個解法尚未嘗試,但我認為應該可以避免掉站台回收的機制

結論
本文僅實作簡單的連線與傳送訊息,WebSocketSharp還包含其他功能,像是對所有Client廣播、Server關閉特定Client的連線、握手請求中以QueryString的方式傳送參數等等,github網站都有詳細的說明與用法。

文章中有錯誤的地方,還請各位前輩不吝指教


尚未有邦友留言

立即登入留言