HTTP回调URL与WebSocket用于异步响应的对比?

1 投票
2 回答
1635 浏览
提问于 2025-04-18 14:09

我有两台服务器:一台是用Golang写的,另一台是用Python(2.7)写的。Python(Bottle)服务器需要执行一个计算密集型的任务,并提供了一个RESTful的接口来启动这个过程。也就是说,Go服务器会发送:

HTTP GET到myserver.com/data

Python服务器执行计算后,需要通知Go服务器这个处理已经完成。我认为可以有两种设计方式:

  1. Go服务器向Python发送一个回调的URL和数据,然后Python通过访问这个URL来回应。例如:

    HTTP GET | myserver.com/data | 数据{callbackURI:goserver.com/process/results, 类型: POST, 响应:"processComplete"}

  2. 让Python通过WebSocket将响应发送回Go服务器。

哪种设计更合适呢?这两种方式各有什么优缺点?除了错误情况(比如服务器崩溃等),Python服务器需要“通知”客户端的唯一事情就是计算完成。这是唯一的响应。

负责Go服务器的团队对基于WebSocket或Ajax的Go客户端不太熟悉(我也不熟悉,我从来没有写过Go代码 :) #1看起来更简单,但我不知道这是否是一种被接受的设计方法,还是说只是个临时解决方案?在这方面有什么推荐的做法吗?

2 个回答

3

如果你想让它符合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。

2

这要看这些信号发送的频率。如果每秒发送很多次,保持一个websocket连接可能更合适。否则,选择第一种方式,因为这样开销更小,连接也更松散。

撰写回答