简体   繁体   English

客户端-服务器套接字设置,如何响应确定的客户端

[英]Client-Server socket setup, how to respond to a determined client

This question has been edited to focus in a simpler problem 该问题已被编辑以关注一个简​​单的问题

So I have a basic client-server socket installation, in which the client send a JSON like {'id': '1', 'value': 'A'} . 因此,我有一个基本的客户端-服务器套接字安装,其中客户端发送JSON,例如{'id': '1', 'value': 'A'} At the server side, if I receive a message with id 2 I want to send a message to the client with id 1 , telling him that his new value is C . 在服务器端,如果我收到id 2的消息,我想向id 1的客户端发送消息,告诉他他的新value C

This message should be "private", ie, only id 1 should receive it, no broadcasting allowed. 此消息应为“私人”,即,只有id 1可以接收它,不允许广播。

How should I approach this problem? 我应该如何解决这个问题? How could I keep track of the connections at the server side so that I could send a message to a determined client? 如何跟踪服务器端的连接,以便可以向确定的客户端发送消息? The problem is that it's the server the one sending the message to the client, not responding to a client's message. 问题是服务器是向客户端发送消息的服务器,而不是响应客户端消息的服务器。 I guess it must be with some combination of threading and queues, but still haven't figured out how to do it. 我想它一定是线程和队列的某种组合,但是仍然没有弄清楚该怎么做。

This is the code I have right now at the server, keeping track of the clients using a dict, but it's not working (bad file descriptor at the sendall('C') line: 这是我现在在服务器上的代码,使用dict跟踪客户端,但是它不起作用( sendall('C')行中的sendall('C')

track_clients = {}
while True:
    print "waiting for a connection"
    connection, client_address = sock.accept()
    try:
        print "connection from ", client_address
        data = json.loads(connection.recv(1024))
        track_clients[data['id']] = connection

        if data['id'] == '2':
            conn = track_clients['1']
            conn.sendall('C')
        connection.sendall(json.dumps(data))
    finally:
        connection.close()

You can have a look at channels http://channels.readthedocs.org/en/latest/ . 您可以查看频道http://channels.readthedocs.org/en/latest/ Alongside redis ( https://pypi.python.org/pypi/redis/ ) 除了redis( https://pypi.python.org/pypi/redis/

Have you considered using zeromq for this task? 您是否考虑过将zeromq用于此任务? It is easy to use and provides high level implementation of common patterns. 它易于使用,并提供了通用模式的高级实现。

From zeromq guide zeromq指南

ZeroMQ (also known as ØMQ, 0MQ, or zmq) looks like an embeddable networking library but acts like a concurrency framework. ZeroMQ(也称为ØMQ,0MQ或zmq)看起来像一个可嵌入的网络库,但是却像一个并发框架。 It gives you sockets that carry atomic messages across various transports like in-process, inter-process, TCP, and multicast. 它为您提供套接字,这些套接字可在各种传输方式(例如进程内,进程间,TCP和多播)中承载原子消息。 You can connect sockets N-to-N with patterns like fan-out, pub-sub, task distribution, and request-reply. 您可以使用扇出,发布-订阅,任务分配和请求-回复等模式将套接字N-to-N连接起来。 It's fast enough to be the fabric for clustered products. 它足够快,可以成为集群产品的基础。 Its asynchronous I/O model gives you scalable multicore applications, built as asynchronous message-processing tasks. 它的异步I / O模型为您提供了可扩展的多核应用程序,这些应用程序是作为异步消息处理任务而构建的。 It has a score of language APIs and runs on most operating systems. 它具有多种语言API,并且可以在大多数操作系统上运行。 ZeroMQ is from iMatix and is LGPLv3 open source. ZeroMQ来自iMatix,是LGPLv3开源。

Also it seems like it better to reuse existing libraries because you can focus on your tasks directly while library provides you with all required high-level methods. 同样,重用现有库似乎更好,因为在库为您提供所有必需的高级方法时,您可以直接关注您的任务。

The code above is OK. 上面的代码可以。 The problem is the connection.close() at the finally statement. 问题是finally语句中的connection.close()。 Removing it, fixes the issue. 删除它可以解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM