SuperWebSocket结合Windows服务实现实时消息

来源:互联网 发布:程序员编辑器排名 编辑:程序博客网 时间:2024/06/05 10:03

打开MyWebSocketService设计视图,右键,添加安装程序,自动添加ProjectInstaller.cs。

打开设计视图,选中ServiceInstaller1,右键修改属性:

    ServiceName(服务名):这里改为我们刚重命名的MyWebSocketService    StartType(启动方式):改为自动启动Automatic    DelayedAutoStart(延迟加载)

选中serviceProcessInstaller1,右键修改属性:

    Account(账户类型):这里改为LocalSystem

添加安装和卸载文件。注意添加文件请使用ANSI编码。推荐使用EditPlus等工具新建文件,然后通过项目添加现有项。

安装时,请关闭360等安全软件,不然会安装失败

注意替换TestWindowsService.exe和MyWebSocketService。右键属性,设置复制到输出目录。

Install.bat

%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe TestWindowsService.exesc config WebSocket监听服务 start= auto Net Start WebSocket监听服务pause

添加App.config,配置IP和Port。

IP地址为本地连接地址,端口号自定义。确保端口号不被占用。
<configuration>  <startup>    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />  </startup>  <appSettings>    <add key="APWebSocketIP" value="192.168.1.199"/>    <add key="APWebSocketPort" value="8200"/>  </appSettings></configuration>

windows服务项目

项目右键,管理Nuget程序包,搜索SuperWebSocket,注意作者为Kerry Jiang。

MyWebSocketService.cs代码:

using System;using System.Collections.Generic;using System.Configuration;using System.Diagnostics;using System.ServiceProcess;using SuperSocket.SocketBase;using SuperWebSocket;namespace SISOService{    public partial class MyWebSocketService : ServiceBase    {        private readonly Dictionary<string, List<string>> msgDictionary = new Dictionary<string, List<string>>();        private string KSessionId;        private string VSessionId;        private WebSocketServer server;        public MyWebSocketService()        {            InitializeComponent();        }        protected override void OnStart(string[] args)        {            string ip = ConfigurationManager.AppSettings["APWebSocketIP"];            string port = ConfigurationManager.AppSettings["APWebSocketPort"];            //WebSocket服务器端启动            server = new WebSocketServer();            if (!server.Setup(ip, int.Parse(port)))            {                LogHelper.WriteFile("WebSocket服务器端启动失败");                //处理启动失败消息                return;            }            //新的会话连接时            server.NewSessionConnected += server_NewSessionConnected;            //会话关闭            server.SessionClosed += server_SessionClosed;            //接收到新的消息时            server.NewMessageReceived += server_NewMessageReceived;            if (!server.Start())            {                LogHelper.WriteFile(string.Format("开启WebSocket服务侦听失败:{0}:{1}", server.Config.Ip, server.Config.Port));                //处理监听失败消息            }        }        private void server_NewMessageReceived(WebSocketSession session, string value)        {            Debug.WriteLine("接收到新的消息:{0}  来自:{1}  时间:{2:HH:MM:ss}", value, session.RemoteEndPoint, DateTime.Now);            if (value.StartsWith("K"))            {                KSessionId = session.SessionID;                //页面已链接                if (!String.IsNullOrEmpty(VSessionId))                    SendMsgToRemotePoint(VSessionId, string.Format("考场发来消息:{0}", value));                    //页面未链接                else                {                    AddMsgToSessionId(VSessionId);                }            }            else if (value.StartsWith("S"))            {                VSessionId = session.SessionID;                //考场已链接                if (!String.IsNullOrEmpty(KSessionId))                    SendMsgToRemotePoint(KSessionId, string.Format("学生A发来消息:{0}", value));                    //考场已断开                else                {                    AddMsgToSessionId(KSessionId);                }            }        }        /// <summary>        ///     添加会话消息        /// </summary>        /// <param name="value"></param>        private void AddMsgToSessionId(string value)        {            if (value != null)            {                //消息列表包含页面会话ID                if (msgDictionary.ContainsKey(value))                {                    msgDictionary[value].Add(value);                }                    //消息列表不包含页面会话ID                else                    msgDictionary.Add(value, new List<string> {value});            }        }        /// <summary>        ///     会话关闭        /// </summary>        /// <param name="session"></param>        /// <param name="value"></param>        private void server_SessionClosed(WebSocketSession session, CloseReason value)        {            Debug.WriteLine("会话关闭,关闭原因:{0}  来自:{1}  时间:{2:HH:MM:ss}", value, session.RemoteEndPoint, DateTime.Now);            if (session.SessionID == KSessionId)                SendMsgToRemotePoint(VSessionId, "考场已断开");            else if (session.SessionID == VSessionId)                SendMsgToRemotePoint(KSessionId, "学生A已断开");        }        /// <summary>        ///     新的会话链接        /// </summary>        /// <param name="session"></param>        private void server_NewSessionConnected(WebSocketSession session)        {            Debug.WriteLine("新的会话连接  来自:{0} SessionID:{1}  时间:{2:HH:MM:ss}", session.RemoteEndPoint, session.SessionID,                DateTime.Now);            if (msgDictionary.ContainsKey(session.SessionID))                msgDictionary[session.SessionID].ForEach(item => session.Send(item));        }        /// <summary>        ///     发送消息到        /// </summary>        /// <param name="sessionId"></param>        /// <param name="msg"></param>        private void SendMsgToRemotePoint(string sessionId, string msg)        {            WebSocketSession allSession = server.GetAppSessionByID(sessionId);            if (allSession != null)                allSession.Send(msg);        }    }}

添加log4net配置文件log4net.config。查看日志。

由于SuperWebSocket已经有日志功能,只需要添加配置文件,即可查看日志。
<?xml version="1.0" encoding="utf-8" ?><log4net>    <appender name="errorAppender" type="log4net.Appender.RollingFileAppender">        <filter type="log4net.Filter.LevelMatchFilter">            <levelToMatch value="ERROR" />        </filter>        <filter type="log4net.Filter.DenyAllFilter" />        <File value="Logs\err.log" />        <appendToFile value="true" />        <rollingStyle value="Date" />        <datePattern value="yyyyMMdd" />        <layout type="log4net.Layout.PatternLayout">            <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />        </layout>    </appender>    <appender name="infoAppender" type="log4net.Appender.RollingFileAppender">        <filter type="log4net.Filter.LevelMatchFilter">            <levelToMatch value="INFO" />        </filter>        <filter type="log4net.Filter.DenyAllFilter" />        <File value="Logs\info.log" />        <appendToFile value="true" />        <rollingStyle value="Date" />        <datePattern value="yyyyMMdd" />        <layout type="log4net.Layout.PatternLayout">            <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />        </layout>    </appender>    <appender name="debugAppender" type="log4net.Appender.RollingFileAppender">        <filter type="log4net.Filter.LevelMatchFilter">            <levelToMatch value="DEBUG" />        </filter>        <filter type="log4net.Filter.DenyAllFilter" />        <File value="Logs\debug.log" />        <appendToFile value="true" />        <rollingStyle value="Date" />        <datePattern value="yyyyMMdd" />        <layout type="log4net.Layout.PatternLayout">            <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />        </layout>    </appender>    <appender name="perfAppender" type="log4net.Appender.RollingFileAppender">        <filter type="log4net.Filter.LevelMatchFilter">            <levelToMatch value="INFO" />        </filter>        <filter type="log4net.Filter.DenyAllFilter" />        <File value="Logs\perf.log" />        <appendToFile value="true" />        <rollingStyle value="Date" />        <datePattern value="yyyyMMdd" />        <layout type="log4net.Layout.PatternLayout">            <conversionPattern value="%date %logger - %message%newline" />        </layout>    </appender>    <root>        <level value="ALL" />        <appender-ref ref="errorAppender" />        <appender-ref ref="infoAppender" />        <appender-ref ref="debugAppender" />    </root>    <logger name="Performance" additivity="false">      <level value="ALL" />      <appender-ref ref="perfAppender" />    </logger></log4net>

在html中使用WebSocket

1.首先考虑浏览器兼容问题。一些低版本浏览器不支持。
2.创建websocket对象,设置ip和端口。

Exam.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">    <head>        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>        <title></title>    </head>    <body>        <h2>考场</h2>        <div>            <script src="Scripts/jquery-1.8.2.js"></script>            <script type="text/javascript">                $(function() {                    var ws;                    var url = "ws://192.168.1.104:8800";                    $("#btnConnection").click(function() {                        if ("WebSocket" in window) {                            ws = new WebSocket(url);                        } else if ("MozWebSocket" in window) {                            ws = new MozWebSocket(url);                        } else                            alert("浏览器版本过低,请升级您的浏览器。\r\n浏览器要求:IE10+/Chrome14+/FireFox7+/Opera11+");                        //注册各类回调                        ws.onopen = function() {                            $("#msg").append("连接服务器成功<br/>");                            ws.send("K:考场已链接");                        };                        ws.onclose = function() {                            $("#msg").append("与服务器断开连接<br/>");                        };                        ws.onerror = function() {                            $("#msg").append("数据传输发生错误<br/>");                        };                        ws.onmessage = function(receiveMsg) {                            $("#msg").append(receiveMsg.data + "<br/>");                        };                    });                    $("#btnSend").click(function() {                        var text = $("#txtContent").val();                        ws.send("K:" + text);                        $("#msg").append("发送信息至服务器:  " + "K:" + text + "<br/>");                    });                });            </script>            <input id="btnConnection" type="button" value="连接" />            <br />            <textarea cols="100" rows="10" id="txtContent"></textarea>            <br />            <input id="btnSend" type="button" value="发送" />            <hr />            <span id="msg"></span>        </div>    </body></html>

Student.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">    <head>        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>        <title></title>    </head>    <body>        <h2>学生A</h2>        <div>            <script src="Scripts/jquery-1.8.2.js"></script>            <script type="text/javascript">                $(function() {                    var ws;                    var url = "ws://192.168.1.104:8800";                    $("#btnConnection").click(function() {                        if ("WebSocket" in window) {                            ws = new WebSocket(url);                        } else if ("MozWebSocket" in window) {                            ws = new MozWebSocket(url);                        } else                            alert("浏览器版本过低,请升级您的浏览器。\r\n浏览器要求:IE10+/Chrome14+/FireFox7+/Opera11+");                        //注册各类回调                        ws.onopen = function() {                            $("#msg").append("连接服务器成功<br/>");                            ws.send("S:学生A已链接");                        };                        ws.onclose = function() {                            $("#msg").append("与服务器断开连接<br/>");                        };                        ws.onerror = function() {                            $("#msg").append("数据传输发生错误<br/>");                        };                        ws.onmessage = function(receiveMsg) {                            $("#msg").append(receiveMsg.data + "<br/>");                        };                    });                    $("#btnSend").click(function() {                        var text = $("#txtContent").val();                        ws.send("S:" + text);                        $("#msg").append("发送信息至服务器:  " + "S:" + text + "<br/>");                    });                });            </script>            <input id="btnConnection" type="button" value="连接" />            <br />            <textarea cols="100" rows="10" id="txtContent"></textarea>            <br />            <input id="btnSend" type="button" value="发送" />            <hr />            <span id="msg"></span>        </div>    </body></html>

模拟一个学生A和考场的交互,如图:

这里写图片描述


这里写图片描述

0 0