@qwead

Как обработать исключение при разрыве соединения?

Взял за основу сервер для чата с гитхаба
spoiler
namespace 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()
  • Вопрос задан
  • 2056 просмотров
Решения вопроса 1
yarosroman
@yarosroman Куратор тега C#
C# the best
Походу я вас очень удивлю, попробуйте блок try - catch.
https://docs.microsoft.com/ru-ru/dotnet/csharp/lan...
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы