源码下载地址:
https://download.csdn.net/download/wysdong/87208870
C# 服务端代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Fleck;//NuGet:FLeck
namespace eldersocket
{
public class FleckSocketServer
{
private List
///
/// 接收数组缓冲区
///
public List
{
get { return _receiveBuffer; }
set { _receiveBuffer = value; }
}
///
/// 是否正在运行中...
///
public bool IsRuning { get; set; }
///
/// WebSocked服务端
///
Fleck.WebSocketServer ws = new Fleck.WebSocketServer("ws://127.0.0.1:678");
///
/// 连接对象池
///
public Dictionary
///
/// 日志改变事件
///
public event EventHandler
///
/// 接受消息事件
///
public event EventHandler
public void Start()
{
IsRuning = true;
try
{
new Thread(() =>
{
#region
ws.Start(socket =>
{
socket.OnOpen = () =>
{
try
{
if (!WebSocketPool.ContainsKey(socket.ConnectionInfo.Id.ToString()))
WebSocketPool.Add(socket.ConnectionInfo.Id.ToString(), new WebSocketConnectionX(socket, DateTime.Now));
//连接后马上发送消息
OnMessageReviced?.Invoke(socket, "connect success......");
socket.Send("连接成功");
}
catch(Exception ex)
{
OnLogWrite?.Invoke(this, "Socket Open Error:" + ex.Message);
}
};
socket.OnClose = () =>
{
try
{
//if (WebSocketPool.ContainsKey(socket.ConnectionInfo.Id.ToString()))
// WebSocketPool.Remove(socket.ConnectionInfo.Id.ToString());
OnLogWrite?.Invoke(this, "Close:[" + WebSocketPool.Count + "]" + socket.ConnectionInfo.ClientPort);
}
catch(Exception ex) { OnLogWrite?.Invoke(this, "Socket Close Error:" + ex.Message); }
};
socket.OnMessage =message =>
{
try
{
if (!string.IsNullOrEmpty(message))
{
if (message.Trim().Contains("ping"))
{
socket.Send("pong");
OnMessageReviced?.Invoke(socket, message);
return;
}
if(message.Trim()== "quit")
{
if (WebSocketPool.ContainsKey(socket.ConnectionInfo.Id.ToString()))
WebSocketPool.Remove(socket.ConnectionInfo.Id.ToString());
}
OnMessageReviced?.Invoke(socket, message);
}
}
catch (Exception ex) { OnLogWrite?.Invoke(this, "Socket OnMessage Error:" + ex.Message); }
};
socket.OnBinary = data =>
{
try
{
string message = Encoding.UTF8.GetString(data);
if(!string.IsNullOrEmpty(message))
{
if (message.Trim().Contains("ping"))
{
socket.Send("pong " + socket.ConnectionInfo.ClientPort.ToString());
return;
}
OnMessageReviced?.Invoke(socket, message);
}
}
catch (Exception ex) { OnLogWrite?.Invoke(this, "Socket OnBinary Error:" + ex.Message); }
};
socket.OnError = mesasge =>
{
try
{
OnLogWrite?.Invoke(this, "Socket OnError:" + mesasge);
}
catch { }
};
});
#endregion
//出错后进行重启
ws.RestartAfterListenError = true;
}).Start();
if (ws.ListenerSocket != null)
OnLogWrite?.Invoke(this, ws.Port + "正在监听中...");
}
catch(Exception ex)
{
OnLogWrite?.Invoke(this, "ws.Start Error:" + ex.Message);
}
}
public void Stop()
{
IsRuning = false;
try
{
OnLogWrite?.Invoke(this, "ws Stoping...");
if (ws != null)
ws.Dispose();
}
catch(Exception ex)
{
OnLogWrite?.Invoke(this, "ws Stop Error:" + ex.Message);
}
}
public void MessageSendtoClient(string msg,string clientid="")
{
try
{
Dictionary
foreach ( var item in _webSocketPool)
{
每次发送前,清理一下无效的ws,也可以在时间线程中清理
//if(!item.Value.WebSocketConnection.IsAvailable)
//{
// item.Value.WebSocketConnection.Close();
// WebSocketPool.Remove(item.Key);
// OnLogWrite?.Invoke(this, item.Key + " is invalid removed");
//}
if (item.Value.WebSocketConnection.IsAvailable && (clientid == item.Value.WebSocketConnection.ConnectionInfo.Id.ToString().Trim() || clientid == ""))
item.Value.WebSocketConnection.Send(msg);
}
}
catch(Exception ex)
{
OnLogWrite?.Invoke(this, "MessageSendtoClient Error:" + ex.Message);
}
}
public void ClientExit(string clientid = "")
{
try
{
foreach (var item in WebSocketPool)
{
//每次发送前,清理一下无效的ws,也可以在时间线程中清理
if (!item.Value.WebSocketConnection.IsAvailable)
{
item.Value.WebSocketConnection.Close();
WebSocketPool.Remove(item.Key);
OnLogWrite?.Invoke(this, item.Key + " is invalid removed");
}
if (item.Value.WebSocketConnection.IsAvailable && (clientid == item.Value.WebSocketConnection.ConnectionInfo.Id.ToString().Trim() || clientid == ""))
item.Value.WebSocketConnection.Close();
}
}
catch (Exception ex)
{
OnLogWrite?.Invoke(this, "ClientExit Error:" + ex.Message);
}
}
public Dictionary
{
try
{
foreach (var item in WebSocketPool)
{
//清理一下无效的ws
if (!item.Value.WebSocketConnection.IsAvailable)
{
item.Value.WebSocketConnection.Close();
WebSocketPool.Remove(item.Key);
OnLogWrite?.Invoke(this, item.Key + " is invalid removed");
}
}
}
catch (Exception ex)
{
OnLogWrite?.Invoke(this, "ClientExit Error:" + ex.Message);
}
return WebSocketPool;
}
}
[Serializable]
public class WebSocketConnectionX
{
public IWebSocketConnection WebSocketConnection { get; set; }
public DateTime LastConnectionTime { get; set; } = new DateTime(1900, 1, 1);
public WebSocketConnectionX(IWebSocketConnection ws, DateTime dt)
{
this.WebSocketConnection = ws;
this.LastConnectionTime = dt;
}
}
}
js客户端代码:
$(function () {
//window.onload = start;
$('#a_sendmsg').on('click', function () {
var msg = $("#getmsg").val();
send(msg,"read");
});
$('#a_clearmsg').on('click', function () {
$('#data_info').empty();
});
init();
});
var socket;
var socketinterval = null;//计时器
var socketagainconnect = false;
var isk = 0;
function init() {
var host = "ws://127.0.0.1:678/";
try {
if (socket != null) {
try {
socket.close();
socket = null;
} catch (ex) {}
}
socket = new WebSocket(host);
socket.onopen = function (msg) {
showmsg("begin connection server....");
};
socket.onmessage = function (msg) {
showmsg("socket receive message:" + msg.data + "");
socketagainconnect = false;
if (socketinterval != null) {
//收到信息,就停止心跳连接
clearInterval(socketinterval);
socketinterval = null;
}
if (interval == null) {
//开启心跳,一直发送ping
heartstart();
}
};
socket.onclose = function (msg) {
if (socketinterval == null && !socketagainconnect) {
console.log("socket.onclose..." + isk);
showmsg("socket server lose connection....");//+isk
//与服务端断开连接后,循环尝试连接
socketinterval = setInterval(init, 5000);
socketagainconnect = true;
isk++;
}
};
}
catch (ex) {
showmsg("web socket error:" + ex + "");
}
}
var msglines = 0;
function showmsg(msg) {
if (msg == undefined || msg == null || msg == "") {
return;
}
if (msg.indexOf('pong') >= 0) {
return;
}
if (msglines > 50) {
$('#data_info').empty();
msglines = 0;
}
msglines = msglines + 1;
var dt = new Date();
var str_dt = dt.getFullYear() + " " + zeroFull((dt.getMonth() + 1), 2) + " " + zeroFull(dt.getDate(), 2) + " " + zeroFull(dt.getHours(), 2) + ":" + zeroFull(dt.getMinutes(), 2) + ":" + zeroFull(dt.getSeconds(),2);
$('#data_info').append("["+str_dt+"] "+msg+"
");
}
function zeroFull(value, len) {
var _value = String(value);
if (len == undefined || len == null || len == "") { len = 2; }
while (_value.length < Number(len)) {
_value = "0" + _value;
}
return _value;
};
//发送消息
function send(msg,cmd) {
if (msg=="") {
return;
}
try {
if (cmd == undefined || cmd == null || cmd == "") {
socket.send(msg);
showmsg("send message: " + msg + "");
}
else {
var msgInfo = {};
msgInfo.cmd = "read";
msgInfo.msg = msg;
var strmsg = JSON.stringify(msgInfo);
socket.send(strmsg);
showmsg("send message: " + strmsg + "");
}
} catch (ex) {
showmsg("web send error: " + ex + "");
}
}
var interval = null;//计时器
function heartstart() {
if (interval != null) {
clearInterval(interval);
interval = null;
}
showmsg("start ping...... ");
send("ping", "");
interval = setInterval(heartsend, 1000*60*3);//每3分钟心跳请求一次
}
function heartsend() {
try {
socket.send('ping');
}
catch (ex) {
showmsg("web send ping error: " + ex + "
stop ping ");
if (interval != null) {
clearInterval(interval);
interval = null;
}
}
}
window.onbeforeunload = function () {
try {
socket.send('quit');
socket.close();
socket = null;
}
catch (ex) {
/* log(ex);*/
}
try {
if (interval != null) {
clearInterval(interval);
interval = null;
}
if (socketinterval != null) {
clearInterval(socketinterval);
socketinterval = null;
}
}
catch (ex) {}
};