【问题标题】:How to respond to a Web Services request via WebSockets如何通过 WebSockets 响应 Web 服务请求
【发布时间】: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();
                }
        }
    }

提前感谢您的帮助

【问题讨论】:

    标签: java web-services websocket jersey jetty


    【解决方案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.Sessionjavax.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 对象有关 - stackoverflow.com/a/15649791/775715
    【解决方案2】:

    您的 websocket 处理程序应该有一个关联的 Connection 实例,您可以在该实例上调用 sendMessage()

    【讨论】:

    • 很抱歉,我没有真正明白你在说什么。我的 websockets 和我的 client2 之间的通信正常。当client1使用webservice时问题就来了。如何在我告诉“执行 ping”(getPing) 和接收的那一刻之间保持同步。
    • @brunettia - 您的代码指示 websockets 调用的无效方法,但您的问题似乎与 webservices 调用有关。是哪个?
    • 实际上都是。 websocket 服务器将接收数据,但采用 void 方法。那么如何将数据发送回网络服务,并让它等待响应!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    相关资源
    最近更新 更多