连接到现有的工人/任务?

时间:2016-08-24 11:04:04

标签: c# .net multithreading subscribe

我想就如何处理我遇到的问题得到一些意见。

假设我有一个服务器和一个客户端。

客户端A连接并要求服务器生成一个从1到9999的新线程。让我们调用此线程A.

客户端B连接并要求服务器生成另一个从9999到1倒计时的线程。让我们调用此线程B.

线程A向调用客户端发送当前计数的更新(即线程A更新客户端A,线程B更新客户端B)。

客户端A然后断开连接并重新连接 - 我的问题是,如何“重新订阅”当前线程并继续获取更新?。

是否有任何现有的图书馆可以帮助完成此类任务?

更新:如果有帮助,可以进一步澄清:

这些服务器线程将在后台持续运行。例如,客户端将连接到服务器并启动任务 - 此任务将消息发送回客户端。用户知道任务已经开始,因为他们的客户端正在接收消息。用户断开客户端连接,但任务仍在后台处理。用户决定检查任务,以便再次启动客户端并连接到服务器。最后一句话就是我想要实现的目标。我很抱歉不清楚。

2 个答案:

答案 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容量及其项目的生命周期。