一、項目創建
1、VS2017創建winform項目
2、Nuget中搜索安裝 SuperWebSocketNETServer
二、WebSocket服務端功能實現
1、由於有使用到log4net,在開始實現功能前,需要對log4net進行相關設置,設置參考https://blog.csdn.net/liwan09/article/details/106266346
2、界面設置
3、實現功能代碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
using SuperWebSocket;
using log4net;
using Bosch.Rtns.Sockect.Model;
using Bosch.Rtns.Sockect.CommonUtils;
namespace Bosch.Rtns.Sockect
{
public partial class frmMain : Form
{
private WebSocketServer webSocketServer;
ILog loggerManager;
Dictionary<WebSocketSession, string> socketSessionList = new Dictionary<WebSocketSession, string>();//記錄鏈接的客戶端數據
public frmMain()
{
InitializeComponent();
}
/// <summary>
/// load
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmMain_Load(object sender, EventArgs e)
{
loggerManager=LogManager.GetLogger("Logger");
txtIPAddress.Text = "127.0.0.1";
txtPort.Text = "1414";
btnEnd.Enabled = false;
}
/// <summary>
///開啓服務
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnStart_Click(object sender, EventArgs e)
{
string ipAddress = txtIPAddress.Text.Trim();
string port = txtPort.Text.Trim();
if (string.IsNullOrEmpty(ipAddress))
{
txtIPAddress.Focus();
MessageBox.Show("請輸入IP地址!");
return;
}
if (string.IsNullOrEmpty(port))
{
txtPort.Focus();
MessageBox.Show("請輸入端口號!");
return;
}
webSocketServer = new WebSocketServer();
webSocketServer.NewSessionConnected += Sockect_NewSessionConnected;
webSocketServer.NewMessageReceived += Sockect_NewMessageReceived;
webSocketServer.SessionClosed += Sockect_SessionClosed;
if (!webSocketServer.Setup(ipAddress,Convert.ToInt32(port)))
{
txtLogInfo.Text += "設置Socket服務偵聽地址失敗!\r\n";
loggerManager.Error("設置Socket服務偵聽地址失敗!\r\n");
return;
}
if (!webSocketServer.Start())
{
txtLogInfo.Text += "啓動WebSocket服務偵聽失敗!\r\n";
loggerManager.Error("啓動WebSocket服務偵聽失敗!\r\n");
return;
}
txtLogInfo.Text += "Socket啓動服務成功!\r\n";
loggerManager.Info("Socket啓動服務成功!\r\n");
txtIPAddress.Enabled = false;
txtPort.Enabled = false;
btnStart.Enabled = false;
btnEnd.Enabled = true;
}
/// <summary>
/// 關閉服務
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnEnd_Click(object sender, EventArgs e)
{
if (webSocketServer != null)
{
webSocketServer.Stop();
webSocketServer = null;
}
txtIPAddress.Enabled = true;
txtPort.Enabled = true;
btnStart.Enabled = true;
btnEnd.Enabled = false;
}
/// <summary>
/// 新的Socket連接事件
/// </summary>
/// <param name="session"></param>
private void Sockect_NewSessionConnected(WebSocketSession session)
{
string logMsg = string.Format("{0} 與客戶端{1}創建新會話", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), GetwebSocketSessionName(session))+"\r\n";
this.Invoke(new Action(() =>
{
txtLogInfo.Text += logMsg;
}));
loggerManager.Info(logMsg);
socketSessionList.Add(session, "");
}
/// <summary>
/// 消息接收事件
/// </summary>
/// <param name="session"></param>
/// <param name="value">接收的消息</param>
private void Sockect_NewMessageReceived(WebSocketSession session, string value)
{
string logMsg = string.Format("{0} 從客戶端{1}接收新的消息:\r\n{2}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), GetwebSocketSessionName(session),value) + "\r\n";
this.Invoke(new Action(() =>
{
txtLogInfo.Text += logMsg;
}));
loggerManager.Info(logMsg);
ReceiveData receiveData = JsonHelper.ConvertToEntity<ReceiveData>(value);
//退出登錄
if (receiveData.MessageType == "3")
{
//調用weiapi接口,更新在線用戶的在線狀態
socketSessionList.Remove(session);
session.Close(SuperSocket.SocketBase.CloseReason.ClientClosing);//斷開連接
}
else
{
if(receiveData.MessageType == "4")//設備故障推送
{
EquipmentFault equipmentFault = JsonHelper.ConvertToEntity<EquipmentFault>(receiveData.MessageContent);
}
else
{
socketSessionList[session] = receiveData.MessageContent;//記錄app端的設備id
}
}
}
/// <summary>
/// sockect客戶端斷開連接事件
/// </summary>
/// <param name="session"></param>
/// <param name="value"></param>
private void Sockect_SessionClosed(WebSocketSession session, SuperSocket.SocketBase.CloseReason value)
{
string logMsg = string.Format("{0} 與客戶端{1}的會話被關閉 原因:{2}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), GetwebSocketSessionName(session), value) + "\r\n";
this.Invoke(new Action(() =>
{
txtLogInfo.Text += logMsg;
}));
loggerManager.Info(logMsg);
socketSessionList.Remove(session);
}
/// <summary>
/// 獲取連接的客戶端的ip地址
/// </summary>
/// <param name="webSocketSession"></param>
private static string GetwebSocketSessionName(WebSocketSession webSocketSession)
{
string id= HttpUtility.UrlDecode(webSocketSession.SessionID);//獲取sessionid
var remoteClient = webSocketSession.RemoteEndPoint;
return remoteClient.Address + ":" + remoteClient.Port.ToString();
}
/// <summary>
/// 發送消息
/// </summary>
/// <param name="session"></param>
/// <param name="msg"></param>
private void SendMessage(WebSocketSession session, string msg)
{
//向所有客戶端發送消息
//foreach (var sendSession in session.AppServer.GetAllSessions())
//{
// sendSession.Send(msg);
//}
session.Send(msg);//向指定的客戶端發送消息
}
}
}
相關實體類代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Bosch.Rtns.Sockect.Model
{
/// <summary>
/// 設備故障信息
/// </summary>
public class EquipmentFault
{
/// <summary>
/// 目標手機設備ID
/// </summary>
public string TargetPhoneID { get; set; }
/// <summary>
/// 故障發生時間
/// </summary>
public DateTime FaultTime { get; set; }
/// <summary>
/// 消息id
/// </summary>
public string MessageUID { get; set; }
/// <summary>
/// 消息標題
/// </summary>
public string MessageTitle { get; set; }
/// <summary>
/// 發送給App(消息類型)
/// </summary>
public string SubAPPname { get; set; }
/// <summary>
/// 故障等級 Low,Default,High,Emergent
/// </summary>
public string EmergenceLevel { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Bosch.Rtns.Sockect.Model
{
/// <summary>
/// 接收的消息
/// </summary>
public class ReceiveData
{
/// <summary>
/// 接收的消息類型 1:App端登錄 2:設備故障信息推送
/// </summary>
public string MessageType { get; set; }
/// <summary>
/// 消息內容
/// </summary>
public string MessageContent { get; set; }
}
}
Json幫助類代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace Bosch.Rtns.Sockect.CommonUtils
{
/// <summary>
/// Json幫助類
/// </summary>
public class JsonHelper
{
/// <summary>
/// object轉json
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string ConvertObjToJson(object obj)
{
return JsonConvert.SerializeObject(obj);
}
/// <summary>
/// Json字符串轉實體類數據
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="jsonValue"></param>
/// <returns></returns>
public static T ConvertToEntity<T>(string jsonValue)
{
return JsonConvert.DeserializeObject<T>(jsonValue);
}
/// <summary>
/// Json字符串轉List<T>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="jsonValue"></param>
/// <returns></returns>
public static List<T> ConvertToList<T>(string jsonValue)
{
return JsonConvert.DeserializeObject<List<T>>(jsonValue);
}
}
}
4、客戶端代碼(html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Web sockets test</title>
<script src="jquery-min.js"></script>
</head>
<body>
<div>
服務器地址:<input type="text" id="serverAddress" value="127.0.0.1:4141" />
<button type="button" οnclick="connectionServer();">連接</button>
<button type="button" οnclick="DisconnectionServer()">斷開</button>
</div>
<div>
<button type="button" οnclick="senMsg()">發送消息</button>
<div>
<textarea id="txtmsg" style="height:200px;width:300px"></textarea>
</div>
</div>
</body>
</html>
<script type="text/javascript">
var ws;
var SocketCreated = false;
var isUserloggedout = false;
var defaultMsg = "{\"MessageType\":\"\",\"MessageContent\":\"\"}";
document.getElementById("txtmsg").value = defaultMsg;
function connectionServer() {
try {
if ("WebSocket" in window) {
ws = new WebSocket("ws://" + document.getElementById("serverAddress").value);
}
else if ("MozWebSocket" in window) {
ws = new MozWebSocket("ws://" + document.getElementById("serverAddress").value);
}
SocketCreated = true;
isUserloggedout = false;
} catch (ex) {
alert("連接失敗");
return;
}
}
function DisconnectionServer() {
if (SocketCreated && (ws.readyState == 0 || ws.readyState == 1)) {
SocketCreated = false;
isUserloggedout = true;
ws.close();
}
}
function senMsg() {
if (SocketCreated) {
var msg = document.getElementById("txtmsg").value;
ws.send(msg);
}
}
</script>