一、项目创建
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" onclick="connectionServer();">连接</button>
<button type="button" onclick="DisconnectionServer()">断开</button>
</div>
<div>
<button type="button" onclick="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>