简体   繁体   English

python - 服务器如何启动与客户端的连接

[英]python - how can server initiate a connection to client

So I created an app where the app connects to the server and tells it to do something. 所以我创建了一个应用程序,应用程序连接到服务器并告诉它做某事。 However the server takes a lot of time to do that thing (like an hour or so). 然而,服务器需要花费大量时间来做这件事(比如一个小时左右)。 So it doesn't make sense to connect the client to the server for that long. 因此,将客户端连接到服务器这么长时间没有意义。 I want that the server must create a connection to the client to inform that he is ready to deliver the end result. 我希望服务器必须创建与客户端的连接,以通知他已准备好交付最终结果。 Then after connection, he sends the data to the client. 然后在连接之后,他将数据发送到客户端。

I am thinking two ideas here: 我在想这里有两个想法:

  1. I can create a server on the client side also, and client can listen for server to connect. 我也可以在客户端创建服务器,客户端可以监听服务器连接。 However my clients are usually some desktop apps or mobile apps with limited resources and some of them also are behind a firewall/NAT. 然而,我的客户通常是一些桌面应用程序或资源有限的移动应用程序,其中一些也在防火墙/ NAT后面。 So even if they have a server running, I am not sure that my main server will be able to connect to them. 因此,即使他们有服务器运行,我也不确定我的主服务器是否能够连接到它们。

  2. The client can keep checking periodically whether the results are prepared or not. 客户可以定期检查结果是否准备好。 This way the client does not have to maintain any server or anything. 这样客户端就不必维护任何服务器或任何东西。 It will be the plain old client server architecture. 它将是普通的旧客户端服务器架构。 But this costs me a lot of un-necessary traffic, as the result may be available within few minutes to few hours. 但这会花费我很多不必要的流量,因为结果可能在几分钟到几小时内可用。 A client constantly pining the server does not seems too good to me. 客户端不断地对服务器进行操作对我来说似乎并不太好。

I first of all have no idea where to start or google this stuff. 我首先不知道从哪里开始或谷歌这个东西。 I know such a thing exists because I see all the time where servers such as "Skype" informs my desktop app that I have a new friend request, or gmail notification system where Google shows a message on my desktop when new mail is received. 我知道存在这样的事情是因为我总是看到“Skype”这样的服务器通知我的桌面应用程序我有新的朋友请求,或gmail通知系统,当收到新邮件时Google在我的桌面上显示一条消息。

Most google searches are yielding the same stuff where the client connects to the server. 大多数谷歌搜索产生与客户端连接到服务器相同的东西。 But the case is opposite here. 但情况恰恰相反。

If this question is not upto standard, a few references would also be great, and I will delete this post. 如果这个问题不符合标准,那么一些引用也会很棒,我将删除这篇文章。 There's a great chance that I am just not thinking something and being stupid. 我很有可能只是没有想到什么和愚蠢的事情。 Please help. 请帮忙。 Thanks. 谢谢。

So after I researched a lot of related articles, here is what I have come up with. 所以在我研究了很多相关文章之后,我就提出了这个问题。

These links describe what is called a "server push" which basically pushes data to the client from server. 这些链接描述了所谓的“服务器推送”,它基本上将数据从服务器推送到客户端。 There are a variety of methods discussed here. 这里讨论了各种方法。 My point #2 was actually very near to the solution, and the term for point #2 is called long polling. 我的观点#2实际上非常接近解决方案,而#2点的术语称为长轮询。

  1. http://en.wikipedia.org/wiki/Push_technology http://en.wikipedia.org/wiki/Push_technology
  2. http://mrjoes.github.io/2013/06/21/python-realtime.html http://mrjoes.github.io/2013/06/21/python-realtime.html
  3. http://flask.pocoo.org/snippets/80/ http://flask.pocoo.org/snippets/80/

But methods discussed in both of these articles are about pushing the data back to the web browser. 但是,这两篇文章中讨论的方法都是将数据推回到Web浏览器。 In some cases, the solution can be extended to server push in mobile clients, but I am still reading on them, so can't comment much. 在某些情况下,解决方案可以扩展到移动客户端中的服务器推送,但我仍在阅读它们,因此无法评论太多。

However, for server to app push, which is kind of what my requirement was, two things really stood up: 但是,对于服务器到应用程序推送,这是我的要求,有两件事情真正起来:

  1. Redis Pub/Sub: The functionality of pub/sub channels in redis is wonderful. Redis Pub / Sub:redis中的pub / sub通道的功能非常棒。 All you have to do is subscribe the clients to the channel in server, and anytime the server publishes something, the clients automatically listen to that. 您所要做的就是将客户端订阅到服务器中的通道,并且只要服务器发布了某些内容,客户端就会自动收听。 Redis is widely used, is well maintained, is easy to use, and is designed for very large scale applications. Redis使用广泛,维护良好,易于使用,专为大规模应用而设计。 I liked that. 我喜欢那个。
  2. Amazon SNS. 亚马逊SNS。 Now people like me (I forgot to mention in the question, that I am using amazon as my servers) using amazon aws, this feature SNS (Simple Notification System) is designed entire for server to app push. 现在人们喜欢我(我忘了在问题中提到,我使用亚马逊作为我的服务器)使用amazon aws,这个功能SNS(简单通知系统)是为服务器到app推送而设计的。 Its cheap, easy to implement and comes with python libraries to use. 它便宜,易于实现,并附带python库使用。 So if you don't want to get in redis, just use this simple tool by amazon to push data to your clients. 因此,如果您不想使用redis,只需使用亚马逊的这个简单工具将数据推送给您的客户。 It also supports to push data directly to SQS (Simple Queue Service), if you ever need it. 如果您需要,它还支持将数据直接推送到SQS(简单队列服务)。

I have currently decided to go with Amazon SNS and will also keep learning Redis side by side, just for future use. 我目前决定使用Amazon SNS,并且还将继续学习Redis,以备将来使用。

Update: 更新:

Need server push? 需要服务器推? Forget everything else and use Redis + Socket-IO + Node-JS. 忘掉其他一切,使用Redis + Socket-IO + Node-JS。 How did I not know about Websockets. 我怎么不知道Websockets。 Its the next best thing. 它是下一个最好的东西。

In my app, I just send any messages to Redis that I want to be pushed to clients. 在我的应用程序中,我只是向Redis发送任何消息,我希望将其推送给客户。 Redis publishes those messages. Redis发布这些消息。 Socket.IO is listening on the channels using psubscribe to listen on patterns rather than one channel. Socket.IO正在使用psubscribe监听频道,而不是一个频道。 Category of user is defined by the channel name. 用户类别由通道名称定义。

Once socket.io (written in node.js) hears about the message, it simply emit those messages to the client. 一旦socket.io(写入的node.js)听见的消息,它只是emit到客户端的消息。 Clients inturn are listening to socket.io on a specific port. 客户端正在侦听特定端口上的socket.io. Socket.io supports rooms like channel in redis. Socket.io支持像redis中的channel一样的rooms

For live examples just google real time chat with socket.io and node.js . 对于实时示例,只需real time chat with socket.io and node.js谷歌real time chat with socket.io and node.js

I will also write some examples if anybody requests me to. 如果有人要求我,我也会写一些例子。 Its real easy. 它真的很容易。

In most cases it is as you say: 在大多数情况下,就像你说的那样:

  1. The client can keep checking periodically whether the results are prepared or not. 客户可以定期检查结果是否准备好。 This way the client does not have to maintain any server or anything. 这样客户端就不必维护任何服务器或任何东西。 It will be the plain old client server architecture. 它将是普通的旧客户端服务器架构。

Because it is easy to implement. 因为它易于实现。

Another thing you can try is UDP-hole-punshing . 你可以尝试的另一件事是UDP-hole-punshing It is not much code but also needs a keep alive signal, I guess. 我想,它不是很多代码,但也需要一个保持活动的信号。 Then the server can send to the client. 然后服务器可以发送到客户端。

A third idea is from pwnat . 第三个想法来自pwnat It works over IP. 它适用于IP。 The client sends out a predefined packet to an address that will not be reached. 客户端将预定义的数据包发送到不会到达的地址。 This allows anyone on the internet to answer if the excact packet is known. 这允许互联网上的任何人在已知精确数据包时回答。 The sending and receiving the packet and the reply require IP-level access which often requires higher privileges. 发送和接收数据包以及回复需要IP级访问,这通常需要更高的权限。

Also you can use UPNP to configure the clients firewall to let through some packets. 您还可以使用UPNP配置客户端防火墙以通过某些数据包。

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

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