Выпуск очереди розеток
Привет всем, у меня есть эта проблема, и я застрял с ней, поэтому любая помощь будет принята с благодарностью
Мне нужно создать модуль сокет-чата (клиент-сервер), и я выполнил почти 80% работы, но теперь я застрял, Сценарий таков, что у меня есть серверное приложение, и клиенты подключаются к нему сейчас, если, скажем, 4 клиента подключены к серверу. каждый из них может общаться друг с другом, один клиент отправит сообщение, а сервер получит это сообщение и передаст его, это работает очень хорошо, но когда 2 или более клиентов отправляют сообщение третьему клиенту одновременно, чем я могу я не получаю одно сообщение, а клиент отключается. Я знаю, что мне нужно создать структуру очереди, но мне это не удается, вот моя структура кода.
StartReceive(SocketAsyncEventArgs) ->
Прежде всего, я вызываю этот метод, чтобы начать прослушивание входящих сообщений.
и когда я получаю одно сообщение, я проверяю, завершено ли оно. Синхронизация или асинхронность.
и после этого есть завершенный io слушатель, который вызывается каждый раз, когда завершается одна операция получения, и в этом завершенном io-методе я вызываю метод processReceive, который используется для обработки полученных чанков, так что, наконец, моя структура кода выглядит следующим образом
StartReceive-> IO Completed -> ProcessReceive
Я спроектировал структуру так, чтобы у каждого клиента был объект Receive SOCKETASYNCEVENTAGRS и Send SOCKETASYNCEVENTAGRS на стороне сервера, и я поддерживаю пул для этого
поэтому каждый клиент получает и отправляет данные через свой собственный объект SOCKETASYNCEVENTAGRS
Мне нужен такой сценарий, что если два или более клиентов отправляют сообщения 3-му клиенту, то 3-й клиент не должен получать все сообщения одновременно, вместо этого он должен иметь структуру очереди и получать одно сообщение за раз и одно и то же для операции отправки
вот часть моего кода
private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs)
{
DataHoldingUserToken receiveSendToken = (DataHoldingUserToken)receiveSendEventArgs.UserToken;
receiveSendEventArgs.SetBuffer(receiveSendToken.bufferOffsetReceive, this.socketListenerSettings.BufferSize);
bool willRaiseEvent = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs);
if (!willRaiseEvent)
{
ProcessReceive(receiveSendEventArgs);
}
}
Это IO завершено
void IO_Completed(object sender, SocketAsyncEventArgs e)
{
DataHoldingUserToken receiveSendToken = (DataHoldingUserToken)e.UserToken;
switch (e.LastOperation)
{
case SocketAsyncOperation.Receive:
ProcessReceive(e);
break;
default:
}
}
и это мой StartReceive с Queue реализован, но он не работает
Queue rec = new Queue();
bool IsExecuted = true;
private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs)
{
if (IsExecuted)
{
DataHoldingUserToken receiveSendToken = (DataHoldingUserToken)receiveSendEventArgs.UserToken;
rec.Enqueue(receiveSendToken);
}
try
{
receiveSendEventArgs.SetBuffer(receiveSendToken.bufferOffsetReceive, this.socketListenerSettings.BufferSize);
bool willRaiseEvent = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs);
if (!willRaiseEvent)
{
ProcessReceive(receiveSendEventArgs);
}
rec.Dequeue();
IsExecuted = true;
}
catch
{
IsExecuted = false;
StartReceive(receiveSendEventArgs);
}
}
ищу достойную помощь или хорошее направление
1 ответ
Я не уверен, является ли это основной причиной вашей проблемы, но мне кажется, что у вас заканчивается DataHoldingUserToken
в какое-то время, потому что вы никогда ничего не делаете с объектами, которые вы удаляете, поэтому вы выбрасываете это.
Также обратите внимание, что рекомендуется использовать универсальную форму класса Queue для нетривиального объекта. Это было бы System.Collections.Generic.Queue<DataHoldingUserToken>
,