# 紀錄 MVC 5 用 WebSocket Server ###### tags: `.NET MVC` ## 介紹 使用 [WebSocketSharp](https://github.com/sta/websocket-sharp) 套件來進行,其實步驟幾乎同參考資料,但參考資料少一個最重要的步驟 --- 釋放。 導致在重新 Deploy 的時候、本端開發測試的時候,呼叫 WebSocketServer.Start() 時發生 Port 被占用的問題。 ## Server ### AppConfig.cs --- 全域變數 ``` public class AppConfig { public static WebSocketServer WebSocketServer { get; set; } } ``` ### Global.asax.cs --- 啟用 WebSocket Server 服務 * 檢查 Port 號是否已被使用 * 釋放 * 宣告 WebSocketBehavior --- NotifyBehavior ( 因 Demo Code 就沒放在別處 ) ``` public class MvcApplication : System.Web.HttpApplication, IDisposable { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); int port = 9380; AppConfig.WebSocketServer = new WebSocketServer(port); AppConfig.WebSocketServer.AddWebSocketService<NotifyBehavior>("/notify"); if (PortInUse(port)) throw new Exception($"WebSocketServer 欲使用的 Port 號已被使用 [Port: {port}]"); AppConfig.WebSocketServer.Start(); } public static bool PortInUse(int port) { bool inUse = false; IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners(); foreach (IPEndPoint endPoint in ipEndPoints) { if (endPoint.Port == port) { inUse = true; break; } } return inUse; } public override void Dispose() { if (AppConfig.WebSocketServer != null) AppConfig.WebSocketServer.Stop(); base.Dispose(); } } 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) { ////傳送訊息至Client //Send(JsonConvert.SerializeObject(new { message = "Close" })); } protected override void OnError(ErrorEventArgs e) { } } ``` ### SomeController.cs --- 使用 WebSocket Server 廣播 ``` public class SomeController : Controller { public ActionResult DoSomethingForAjax() { // do... read data something for (int i = 0 ; i<100 ; i++) { // notify client AddConsoleMessage($"when read at data index {i} error.") } // finish AddConsoleMessage("i'm done what you want.") } private void AddConsoleMessage(string message) { if (AppConfig.WebSocketServer != null || AppConfig.WebSocketServer.IsListening) AppConfig.WebSocketServer.WebSocketServices["/notify"].Sessions.Broadcast(JsonConvert.SerializeObject(new { message = message })); LogUtility.Info(message); } } ``` ## Client ### Html ``` <label class="badge rounded-pill bg-secondary mb-1 fs-6">Console:</label> <br /> <textarea id="consoleArea" readonly style="height: 150px; width:100%"></textarea> ``` ### Script ``` var wsc; $(function () { if ("WebSocket" in window) { wsc.onopen = function () { console.log("connected"); $("#consoleLabel").removeClass("bg-secondary"); $("#consoleLabel").addClass("bg-success"); $("#no-connect-wsc-tip").hide(); //傳送訊息至Server //wsc.send('Client Connected.'); }; wsc.onclose = function () { console.log("closed"); $("#consoleLabel").removeClass("bg-success"); $("#consoleLabel").addClass("bg-secondary"); $("#no-connect-wsc-tip").show(); }; wsc.onmessage = function (e) { //接收Server傳入的訊息 var data = JSON.parse(e.data); var $textarea = $('#consoleArea'); $textarea.html($textarea.html() + "\r\n" + data.message) $textarea.scrollTop($textarea[0].scrollHeight); }; wsc.onerror = function (e) { $("#no-connect-wsc-tip").show(); console.log("Error"); } } } ``` ## 參考資料 [C# WebSocket實作雙向通訊](https://ithelp.ithome.com.tw/articles/10256563?sc=rss.qu) [C#指定指定端口是否已经被占用的代码](https://cloud.tencent.com/developer/article/1896178)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up