Взял за основу сервер для чата с
гитхабаspoilernamespace WebSocketChatServer
{
using System;
using System.Collections.Generic;
using Fleck;
using Newtonsoft.Json;
public class WebSocketChatServer
{
private string[] args;
private string hostname = string.Empty;
private int port = 0;
private Dictionary<Fleck.IWebSocketConnection, string> connectedSockets =
new Dictionary<IWebSocketConnection, string>();
private Fleck.WebSocketServer server = null;
private string connectionInfo = string.Empty;
private string consoleInput = string.Empty;
public WebSocketChatServer(string[] args)
{
this.args = args;
FleckLog.Level = LogLevel.Info;
}
public static void Main(string[] args)
{
WebSocketChatServer webSocketChatServer;
try
{
// Create object. Constructor starts the server
webSocketChatServer = new WebSocketChatServer(args);
webSocketChatServer.StartWebSocketChatServer();
}
catch (ArgumentException e)
{
Console.WriteLine(e.ToString());
}
}
public void StartWebSocketChatServer()
{
// Check given arguments
if (this.args.Length < 2 || this.args.Length > 2)
{
Console.WriteLine("Illegal arguments. Usage: <hostname> <port>");
Console.WriteLine("Press <RETURN> to close WebSocket server...");
Console.ReadLine();
throw new ArgumentException("Illegal arguments. Usage: <hostname> <port>");
}
try
{
this.hostname = this.args[0];
this.port = int.Parse(this.args[1]);
this.connectionInfo = "ws://" + this.hostname + ":" + this.port;
this.server = new Fleck.WebSocketServer(this.connectionInfo);
this.server.Start(socket =>
{
socket.OnOpen = () => this.OnOpen(socket);
socket.OnMessage = message => this.OnMessage(socket, message);
socket.OnError = message => this.OnError(socket, message);
socket.OnClose = () => this.OnClose(socket);
});
}
catch (Exception e)
{
FleckLog.Error(e.ToString());
}
while (Console.ReadLine() != "exit")
{
}
}
private void OnMessage(IWebSocketConnection socket, string message)
{
string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string uid = string.Empty;
ChatMessage chatMessage = new ChatMessage();
try
{
if (this.connectedSockets.ContainsKey(socket))
{
uid = this.connectedSockets[socket];
chatMessage.ts = timestamp;
chatMessage.uid = uid;
chatMessage.msg = message;
FleckLog.Info("Msg rcv: " + uid + " @ " + timestamp + " => " + message);
foreach (KeyValuePair<Fleck.IWebSocketConnection, string> client in this.connectedSockets)
{
client.Key.Send(JsonConvert.SerializeObject(chatMessage));
}
}
else
{
if (!this.connectedSockets.ContainsValue(message))
{
this.connectedSockets.Add(socket, message);
FleckLog.Info("Client <" + socket.ConnectionInfo.ClientIpAddress + "> set user name to <" + message + ">");
}
else
{
chatMessage.ts = timestamp;
chatMessage.uid = message;
chatMessage.msg = "Error: the user name <" + message + "> is already in use!";
socket.Send(JsonConvert.SerializeObject(chatMessage));
socket.Close();
if (this.connectedSockets.ContainsKey(socket))
{
this.connectedSockets.Remove(socket);
}
}
}
}
catch (Exception e)
{
FleckLog.Error("Error opening WebSocket on <" + this.connectionInfo + ">. WebSocket maybe in use?");
FleckLog.Error("Exception string: \n" + e.ToString());
Console.ReadLine();
System.Environment.Exit(-1);
}
}
private void OnOpen(IWebSocketConnection socket)
{
FleckLog.Info("Client <" + socket.ConnectionInfo.ClientIpAddress + "> connected");
}
/// <summary>
/// Method called when a client disconnects from the server WebSocket.
/// </summary>
/// <param name="socket">The client that disconnects.</param>
private void OnClose(IWebSocketConnection socket)
{
// If socket is stored in connected sockets list, remove it
if (this.connectedSockets.ContainsKey(socket))
{
this.connectedSockets.Remove(socket);
}
}
private void OnError(IWebSocketConnection socket, Exception exception)
{
FleckLog.Info("Error with client <" + socket.ConnectionInfo.ClientIpAddress + ">: " + exception.ToString());
}
} // END class WebSocketExample
}
В принципе всё работает, и сообщения уходят, но только как клиент отключается, на сервере сразу же возникает исключение
System.Net.Sockets.SocketException
C:\Users\ALEXANDER>D:\downloads\ws\WebSocket-Chat-Server-master\WebSocket-Chat-Server-master\WebSocketServer\bin\Debug\WebSocketServer.exe 127.0.0.1 5432
23.12.2017 10:01:17 [Info] Server started at ws://127.0.0.1:5432
23.12.2017 10:01:35 [Info] Client <127.0.0.1> connected
23.12.2017 10:01:35 [Info] Client <127.0.0.1> set user name to
23.12.2017 10:01:40 [Info] Msg rcv: alex @ 2017-12-23 10:01:40 => hello wrold
23.12.2017 10:01:48 [Info] Error with client <127.0.0.1>: System.IO.IOException: Не удается прочитать данные из транспортного соединения: Программа на вашем хост-компьютере разорва
ла установленное подключение. ---> System.Net.Sockets.SocketException: Программа на вашем хост-компьютере разорвала установленное подключение
в System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state)
в System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
--- Конец трассировки внутреннего стека исключений ---
spoiler в System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
в Fleck.SocketWrapper.<>c__DisplayClassa.b__6(AsyncCallback cb, Object s)
в System.Threading.Tasks.TaskFactory`1.FromAsyncImpl(Func`3 beginMethod, Func`2 endFunction, Action`1 endAction, Object state, TaskCreationOptions creationOptions)
в Fleck.SocketWrapper.Receive(Byte[] buffer, Action`1 callback, Action`1 error, Int32 offset)
в Fleck.WebSocketConnection.Read(List`1 data, Byte[] buffer)
в Fleck.WebSocketConnection.<>c__DisplayClassb.b__a(Int32 r)
в Fleck.SocketWrapper.<>c__DisplayClassa.b__8(Task`1 t)
в System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
в System.Threading.Tasks.Task.Execute()
23.12.2017 10:01:48 [Error] Application Error System.IO.IOException: Не удается прочитать данные из транспортного соединения: Программа на вашем хост-компьютере разорвала установле
нное подключение. ---> System.Net.Sockets.SocketException: Программа на вашем хост-компьютере разорвала установленное подключение
в System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state)
в System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
--- Конец трассировки внутреннего стека исключений ---
в System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
в Fleck.SocketWrapper.<>c__DisplayClassa.b__6(AsyncCallback cb, Object s)
в System.Threading.Tasks.TaskFactory`1.FromAsyncImpl(Func`3 beginMethod, Func`2 endFunction, Action`1 endAction, Object state, TaskCreationOptions creationOptions)
в Fleck.SocketWrapper.Receive(Byte[] buffer, Action`1 callback, Action`1 error, Int32 offset)
в Fleck.WebSocketConnection.Read(List`1 data, Byte[] buffer)
в Fleck.WebSocketConnection.<>c__DisplayClassb.b__a(Int32 r)
в Fleck.SocketWrapper.<>c__DisplayClassa.b__8(Task`1 t)
в System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
в System.Threading.Tasks.Task.Execute()