HTTP回调URL与WebSocket用于异步响应的对比?
我有两台服务器:一台是用Golang写的,另一台是用Python(2.7)写的。Python(Bottle)服务器需要执行一个计算密集型的任务,并提供了一个RESTful的接口来启动这个过程。也就是说,Go服务器会发送:
HTTP GET到myserver.com/data
Python服务器执行计算后,需要通知Go服务器这个处理已经完成。我认为可以有两种设计方式:
Go服务器向Python发送一个回调的URL和数据,然后Python通过访问这个URL来回应。例如:
HTTP GET | myserver.com/data | 数据{callbackURI:goserver.com/process/results, 类型: POST, 响应:"processComplete"}
让Python通过WebSocket将响应发送回Go服务器。
哪种设计更合适呢?这两种方式各有什么优缺点?除了错误情况(比如服务器崩溃等),Python服务器需要“通知”客户端的唯一事情就是计算完成。这是唯一的响应。
负责Go服务器的团队对基于WebSocket或Ajax的Go客户端不太熟悉(我也不熟悉,我从来没有写过Go代码 :) #1看起来更简单,但我不知道这是否是一种被接受的设计方法,还是说只是个临时解决方案?在这方面有什么推荐的做法吗?
2 个回答
如果你想让它符合RESTful的标准,当客户端请求 HTTP GET myserver.com/data
时,服务器应该返回一个 202 Accepted
的状态码:
202 Accepted
请求已经被接受处理,但处理还没有完成。 这个请求可能会被处理,也可能不会,因为在实际处理时可能会被拒绝。对于这种异步操作,没有办法重新发送状态码。
202的响应是故意不做承诺的。它的目的是让服务器可以接受一个请求去进行其他的处理(比如说每天只运行一次的批处理),而不需要用户的连接一直保持到处理完成。返回的内容应该包含请求当前状态的指示,或者一个状态监控的链接,或者一个大概的时间估计,让用户知道什么时候可以期待请求完成。
Python服务器可以返回一个预计完成时间(ETA)和一个临时资源的URL,让用户可以请求当前操作的状态(例如: myserver.com/temp_data?processing_status
)。然后就由Go客户端来等待这个任务完成,通过请求这个资源并查看ETA。一旦处理完成,Python服务器可以返回一个 410 Gone
的状态,并提供新资源的最终URL。
这要看这些信号发送的频率。如果每秒发送很多次,保持一个websocket连接可能更合适。否则,选择第一种方式,因为这样开销更小,连接也更松散。