SuperWebSocket在WebService中的應用
最開始使用是寄托在IIS中,發布之后測試時半個小時就會斷開,所以改為WindowsService
1. 新建Windows服務項目【TestWindowsService】,重命名Service1為MyWebSocketService
2. 打開MyWebSocketService設計視圖,右鍵,添加安裝程序,自動添加ProjectInstaller.cs。
打開設計視圖,選中ServiceInstaller1,右鍵修改屬性:
- ServiceName(服務名):這里改為我們剛重命名的MyWebSocketService
- StartType(啟動方式):改為自動啟動Automatic
- DelayedAutoStart(延遲加載)
選中serviceProcessInstaller1,右鍵修改屬性:
- Account(賬戶類型):這里改為LocalSystem
3. 添加安裝和卸載文件。注意添加文件請使用ANSI編碼。推薦使用EditPlus等工具新建文件,然后通過項目添加現有項。
注意替換TestWindowsService.exe和MyWebSocketService。右鍵屬性,設置復制到輸出目錄。
Install.bat:
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe TestWindowsService.exe
sc config MyWebSocketService start= auto
Net Start MyWebSocketService
pause
Uninstall.bat
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u TestWindowsService.exe
4. 添加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>
5. 修改MyWebSocketService服務代碼。
推薦手動加載dll,通過Nuget加載時,添加依賴的Log4net版本與SuperWebSocket中調用的Log4net版本存在沖突。
log4net版本為1.2.11.0
項目右鍵,管理Nuget程序包,搜索SuperWebSocket,注意作者為Kerry Jiang。
WebSocketServer server;
protected override void OnStart(string[] args)
{
var ip = ConfigurationManager.AppSettings["APWebSocketIP"];
var port = ConfigurationManager.AppSettings["APWebSocketPort"];
//WebSocket服務器端啟動
server = new WebSocketServer();
if (!server.Setup(ip, int.Parse(port)))
{
//Debug.Write("WebSocket服務器端啟動失敗");
//處理啟動失敗消息
return;
}
//新的會話連接時
server.NewSessionConnected += server_NewSessionConnected;
//會話關閉
server.SessionClosed += server_SessionClosed;
//接收到新的消息時
server.NewMessageReceived += server_NewMessageReceived;
if (!server.Start())
{
//Debug.Write(string.Format("開啟WebSocket服務偵聽失敗:{0}:{1}", server.Config.Ip, server.Config.Port));
//處理監聽失敗消息
return;
}
}
string KSessionId;
string VSessionId;
Dictionary<string, List<string>> msgDictionary = new Dictionary<string, List<string>>();
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, SuperSocket.SocketBase.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)
{
var allSession = server.GetAppSessionByID(sessionId);
if (allSession != null)
allSession.Send(msg);
}
6.添加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和端口。
var ws;
var url = "ws://192.168.1.199:8200";
$("#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/>");
}
});
這里模擬一個學生A和考場的交互。
首先連接考場。
接着連接考生。
考場發送消息,通知學生開始考試。
學生接到消息,開始答題。
考試收到考生開始答題消息。
發布
1.首先拷貝TestWebService中的bin\Debug|Release中生成的文件到服務器。通過開始→運行→cmd→ipconfig,查看服務器的本地鏈接地址(192開頭)。修改App.config中的IP和端口號。
2.雙擊Install.bat文件,等待安裝服務。
3.修改html中的WebSocket對象的ip和端口號。這里的ip為服務器固定ip,與WebSocket配置不同。
4.如果涉及到讀寫文件,請在服務器端類360安全衛士等軟件添加信任。
通過Install.bat無法啟動時,可以查看本地日志文件和控制面板的事件管理器,定位詳細錯誤。
源代碼下載:TestWebSocket.zip
轉載請注明出處:http://xcong.cnblogs.com