сервер websocket-sharp отправляет дубликаты сообщений

Вот это шумиха.

Я создаю сетевое приложение, используя websocket-sharp, и столкнулся с проблемой, когда сервер отправляет клиенту сотни (не всегда одинаковое количество) повторяющихся сообщений, вот разбивка.

1.) Клиент подключается (Это рукопожатие работает нормально).

2.) При подключении клиента сервер отправляет указанному клиенту идентификатор сеанса, созданный для этого подключения. (Это работает)

3.) Клиент получает и сохраняет идентификатор сеанса. (Это работает, и дубликаты сюда не отправляются)

4.) Клиент отправляет запрос в систему лобби на сервере для создания матча. (Это работает и принимается правильно)

5.) Сервер получает запросы на создание совпадения, создает совпадение и отправляет данные совпадения обратно клиенту (фактически отправляется одно сообщение, но клиент получает сотни одинаковых сообщений (все сообщения имеют одинаковый размер и содержат одинаковую информацию). )).

Я просмотрел логику своей системы лобби, и нет цикла, который мог бы отправлять ответ о создании матча несколько раз, кроме того, я знаю, что метод «Отправить» на сервере вызывается только один раз.

Я просмотрел документацию по websocket-sharp, я подумал, что, может быть, каким-то образом из одного соединения были сделаны сотни сеансов или что-то бессмысленное в этих строках, но я подключаю одного клиента, и только один сеанс завершается:/

Дайте мне знать, если у вас есть какие-либо идеи, как это могло произойти. Заранее спасибо.

См. код ниже.

Сервер:

Способ отправки:

public void Send (string path, string targetID, string script, string method, params object[] data) {
    print ("SERVER: Sending Message");
    WebSocketServiceHost host = null;
    GetSocketServer ().WebSocketServices.TryGetServiceHost (path, out host);
    if (host != null) {
        Network.Packet packet = new Network.Packet ("Server", targetID, script, method, data);
        if (targetID != "Broadcast") {
            GetSocketServer ().WebSocketServices.Broadcast (Formatter.singleton.Serialize (packet));
        } else if (targetID == "Service") {
            host.Sessions.Broadcast (Formatter.singleton.Serialize (packet));
        } else {
            host.Sessions.SendToAsync (Formatter.singleton.Serialize (packet), targetID);
        }
    }
}

Клиент:

Методы получения:

GetPersistent ().OnMessage += MessageHandler;

void MessageHandler (object sender, MessageEventArgs e) {
    Debug.Log ("CLIENT: Message Recieved");
    Network.singleton.Recieve (e.RawData);
}

Сеть: (используется как сервером, так и клиентом)

Методы получения:

public void Recieve (byte[] data) {
    object obj = Formatter.singleton.Deserialize (data);
    messages.Add (messages.Count, obj);
}

IEnumerator ProcessorCoro () {
    WaitForSeconds delay = new WaitForSeconds (Time.deltaTime);
    while (true) {
        if (messages.Count >= 1) {
            Process (messages [(messages.Count - 1)]);
            messages.Remove ((messages.Count - 1));
        } 
        yield return delay;
    }
}

public void Process (object data) {
    Network.Packet packet = (Network.Packet)data;
    switch (packet.script) {
    case "Home":
        Home.singleton.SendMessage (packet.method, data, SendMessageOptions.DontRequireReceiver);
        break;
    case "Arena":
        Arena.singleton.SendMessage (packet.method, data, SendMessageOptions.DontRequireReceiver);
        break;
    case "Client":
        Client.singleton.SendMessage (packet.method, data, SendMessageOptions.DontRequireReceiver);
        break;
    case "Database":
        Database.singleton.SendMessage (packet.method, data, SendMessageOptions.DontRequireReceiver);
        break;
    }
}

person Sean Barnard    schedule 30.03.2017    source источник
comment
Говоря «получает сотни одинаковых сообщений», вы имеете в виду, что MessageHandler() вызывается сотни раз, и поэтому Process() вызывается сотни раз, или просто Process() вызывается сотни раз?   -  person Chong    schedule 31.03.2017
comment
Вызывается MessageHandler. Он выводит файл debug.log на консоль.   -  person Sean Barnard    schedule 01.04.2017
comment
Меня очень смущает GetPersistent() в вашем коде. Я не нашел эту функцию ни в библиотеке Unity, ни в исходном коде websocket-sharp. Это функция, которую вы написали для создания соединения с вашим веб-сокетом на вашем сервере?   -  person Chong    schedule 02.04.2017
comment
@Chong Да, вы можете установить несколько соединений для каждого клиента, в моем случае у меня было временное и постоянное соединение. Этот вызов был просто для делегирования события этому соединению. Эта часть работает, если бы это было не так, я бы вообще не обрабатывал com.   -  person Sean Barnard    schedule 14.05.2017


Ответы (1)


На стороне клиента вам необходимо убедиться, что вы вызываете следующую строку только один раз

GetPersistent ().OnMessage += MessageHandler;

В противном случае вы будете регистрировать один и тот же обработчик несколько раз для получения сообщения.


Примечание. Такое поведение может потребоваться, если вы хотите прикрепить несколько обработчиков к одному и тому же событию OnMessage.

person weshouman    schedule 30.11.2018