我想就如何处理我遇到的问题得到一些意见。
假设我有一个服务器和一个客户端。
客户端A连接并要求服务器生成一个从1到9999的新线程。让我们调用此线程A.
客户端B连接并要求服务器生成另一个从9999到1倒计时的线程。让我们调用此线程B.
线程A向调用客户端发送当前计数的更新(即线程A更新客户端A,线程B更新客户端B)。
客户端A然后断开连接并重新连接 - 我的问题是,如何“重新订阅”当前线程并继续获取更新?。
是否有任何现有的图书馆可以帮助完成此类任务?
更新:如果有帮助,可以进一步澄清:
这些服务器线程将在后台持续运行。例如,客户端将连接到服务器并启动任务 - 此任务将消息发送回客户端。用户知道任务已经开始,因为他们的客户端正在接收消息。用户断开客户端连接,但任务仍在后台处理。用户决定检查任务,以便再次启动客户端并连接到服务器。最后一句话就是我想要实现的目标。我很抱歉不清楚。
答案 0 :(得分:1)
要解决您的问题,请尝试以下方法:
断开连接时向服务器发出通知 "身份验证"使用GUID创建并在第一次连接和重新连接时发送到服务器。
服务器获取GUID,将它们保存到列表中并查看服务器获取GUID的每个连接,查找现有条目,如果有条目,则表示客户端已连接。如果没有,那么客户端还没有连接,所以服务器必须创建一个新线程。
您可以使用所有其他唯一ID(例如MAC,硬件校验和等)来代替GUID。
答案 1 :(得分:0)
这是可以做什么的抽象例子。由于问题没有指定具体的API,我将使用虚构的名称和类。
为了识别客户端,我们将使用一些唯一的识别令牌,我们称之为ClientToken
。令牌将在第一个客户端连接上分配。它将返回给客户端进行进一步的身份验证,服务器也将使用它来处理任务的跟踪。
跟踪部分是从令牌到任务数据的一些字典。任务数据是一对任务及其消息的队列:
private readonly ConcurrentDictionary<ClientToken, TaskData> m_tasks;
class TaskData
{
public Task ProcessingTask { get; set; }
public BlockingCollection<Message> TaskMessages { get; } =
new BlockingCollection<Message>();
}
假设ClientA通过任何方式连接到服务器。负责连接的部分如下所示:
//this is a kind of event handler, we should'n 'await' on it
async void OnClientConnectedAsync(Client client)
{
var token = client.GetToken();
TaskData taskData;
if (token != null && m_tasks.TryGetValue(token, out taskData))
{
await ProcessMessagesAsync(taskData);
}
else
{
taskData = new TaskData();
token = GenerateUniqueTokenBasedOnTheClientParameters(client);
await client.SetTokenAsync(token);
if (m_tasks.TryAdd(token, taskData))
{
taskData.ProcessingTask =
InitProcessingTask(
taskData.Messages, //will be used by the
client);
await ProcessMessagesAsync(taskData);
}
}
}
async Task ProcessMessagesAsync(TaskData taskData)
{
while (client.IsConnected)
{
var message = taskData.Messages.Take();
await client.SendAsync(message);
}
}
您应该决定Messages
容量及其项目的生命周期。