如何通过 WebSockets 响应 Web 服务请求
Posted
技术标签:
【中文标题】如何通过 WebSockets 响应 Web 服务请求【英文标题】:How to respond to a Web Services request via WebSockets 【发布时间】:2013-06-18 11:26:47 【问题描述】:我在服务器和客户端之间有一个 WebSockets 连接。这使我可以向客户发送命令,他会用数据回应我。服务器也有网络服务。然后我可以说,“在那个客户端上执行这个命令”。所以我们有:
Client1 ---webservices--> 服务器 ---websockets---> Client2
问题是,从Client2接收数据的服务器上的方法是void。
如何将数据发送回 Client1 ?
网络服务:
@Path("/ws")
public class QOSResource
public QOSResource()
@Produces(MediaType.TEXT_PLAIN)
@Path("/ping/macAddr")
@GET
public String getPing(@PathParam("macAddr") String macAddr)
return"Mac adresse : "+macAddr;
//WebSocketsCentralisation.getInstance().ping(macAddr);
WebSockets
@OnWebSocketMessage
public **void** onText(Session session, String message)
if (session.isOpen())
if(firstConnection)
firstConnection = false;
this.macAddr = message;
WebSocketsCentralisation.getInstance().join(this);
ObjectMapper mapper = new ObjectMapper();
Object o;
try
o = mapper.readValue(message, Object.class);
if(o instanceof PingResult)
**// TODO return result to ws**
catch (JsonParseException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (JsonMappingException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
提前感谢您的帮助
【问题讨论】:
【参考方案1】:您在方法参数中获得的Session 对象包含您与远程端点的对话范围。
您需要使用Session.getRemote() 返回的RemoteEndpoint 来发送消息。
例子:
// Send BINARY websocket message (async)
byte data[] = mapper.toBytes(obj);
session.getRemote().sendBytesByFuture(data);
// Send TEXT websocket message (async)
String text = mapper.toString(obj);
session.getRemote().sendStringByFuture(text);
请注意,如果远程端点连接不再处于打开状态(例如远程端点向您发送消息然后立即启动 CLOSE 握手的情况),则 session.getRemote() 调用将引发 WebSocketException控制消息)。
// How to handle send message if remote isn't there
try
// Send message to remote
session.getRemote().sendString(text);
catch(WebSocketException e)
// WebSocket remote isn't available.
// The connection is likely closed or in the process of closing.
注意:这种风格的 websocket 使用,你有一个 Session 和一个 RemoteEndpoint 与即将推出的 JSR-356 标准 (javax.websocket
) 一致。在标准 API 中,您可以使用 javax.websocket.Session
和 javax.websocket.RemoteEndpoint
。
【讨论】:
对不起,我想我不能用英语正确解释自己(我说法语)。你在这里解释的是对的,我使用它。我的问题出在哪里:我的服务器同时具有 websockets 和 webservices。网络服务允许我通过网络套接字访问客户端。在我的示例中,我想获取远程设备的 ping。所以我使用 API /ws/ping/macAddr。在这里,我可以访问正确的会话并发送我的命令(ping)。我不能做的是得到答案,因为服务器上通过 websockets 接收数据的方法是无效的。 没错,用于 WebSocket @onMessage 调用的 Jetty API 的返回类型为void
。这是因为 Jetty 内部 WebSocket 解析器最终会调用此消息并且不期望返回类型。即将推出的 Jetty 9.1 将支持 JSR-356 (javax.websocket) 并且它具有用于 @OnMessage 调用的返回类型的概念,但请注意,这也由 WebSocket 实现管理,您不能挂钩此 JSR-356 返回在 websockets 之外输入。
所以这是我的问题 :) 如果“onText”方法无效,我如何将响应发送回我的网络服务...
onText
是 WebSocket 实现使用的方法。由于需要跟踪和查找 Session 参数,因此很难随意使用它。考虑一个新方法,比如 String onWebsocketMessage(String message)
并在那里执行逻辑,让 onText
只需使用这个新方法并返回响应。
这个其他答案可能与跟踪多个 websocket 的 Session
对象有关 - ***.com/a/15649791/775715【参考方案2】:
您的 websocket 处理程序应该有一个关联的 Connection 实例,您可以在该实例上调用 sendMessage()
。
【讨论】:
很抱歉,我没有真正明白你在说什么。我的 websockets 和我的 client2 之间的通信正常。当client1使用webservice时问题就来了。如何在我告诉“执行 ping”(getPing) 和接收的那一刻之间保持同步。 @brunettia - 您的代码指示 websockets 调用的无效方法,但您的问题似乎与 webservices 调用有关。是哪个? 实际上都是。 websocket 服务器将接收数据,但采用 void 方法。那么如何将数据发送回网络服务,并让它等待响应!以上是关于如何通过 WebSockets 响应 Web 服务请求的主要内容,如果未能解决你的问题,请参考以下文章
通过 GAE 标准上的 Websockets 订阅 GraphQL 没有响应