获取Jetty WebSocket与JavaScript WebSocket通信相同的语言

huangapple go评论95阅读模式
英文:

Getting Jetty Websocket talking same language as JavaScript Websocket

问题

我编写了一个Jetty WebSocket客户端,它连接到远程服务器并尝试发送JSON请求。服务器将这些请求拒绝为无效,并关闭我的连接。然而,当我使用JavaScript客户端发送完全相同的JSON时,它可以正常工作。所以现在我左右为难,是不是因为Jackson 2对JSON的编码与JSON.stringify()不同?(差异显示两个JSON输出完全相同,没有差异)。是不是JavaScript Websockets和Jetty之间有不同的默认配置?我肯定漏掉了什么,一直在为此苦恼。

Java代码片段:

final String wsAddress = "ws://" + wssUrl + "/ws";
final WebSocketClient client = new WebSocketClient();
final WSEventSocket socket = new WSEventSocket(loginRequest);
try {
    client.start();

    final ClientUpgradeRequest request = new ClientUpgradeRequest();
    final URI wsUri = new URI(wsAddress);

    logger.info("Connecting to {}", wsUri);
    final Future<Session> session = client.connect(socket, wsUri, request);

    final String requestjson = mapper.writeValueAsString(wsRequestPojo);
    final Future<Void> fut = session.getRemote().sendStringByFuture(requestjson);
...

JavaScript代码片段:

var wsRequestJson = {...从Java代码片段获取输出...}
var mySock = new WebSocket("ws://" + wsocketUrl + "/ws");
mySock.onmessage = function(evt) { console.log(evt.data); };
mySock.onclose = function() { console.log("CLOSED"); };
mySock.send(JSON.stringify(wsRequestJson));

JavaScript端完美运行,而Java端未正确编码数据。我尝试过一些方法,比如将JSON转换为字节数组等,但没有成功。我使用Wireshark对这两个交互进行了抓包,看到了WebSocket的推送和响应。在Java端,我看到一个看起来像JSON的有效载荷,并且Wireshark可以解析它。在JavaScript数据包中,我看到一些编码数据,例如\214P\311n\3020\024...我稍微了解了一下有关掩码有效载荷的内容,两个客户端都发送了带有掩码密钥的掩码有效载荷,也许与此有关?

有没有什么想法可以让Java的Jetty端以类似的方式编码数据?或者甚至知道JavaScript端正在使用哪种编码方式?我可能在这一点上想得太多了...

谢谢!

英文:

I wrote a Jetty Websocket Client which is connecting to a remote server and trying to send JSON requests. The server is rejecting the requests as invalid and closing my connection. However, when I send the exact same JSON over using a Javascript client it works just fine. So now I'm left scratching my head is it Jackson 2's encoding of the JSON vs JSON.stringify()? (diff shows the two JSON outputs as exactly the same, no diffs). Is it a different default configuration between Javascript Websockets and Jetty? I'm definitely missing something, bashing my head against the wall.

Java Side Snippet:

final String wsAddress = &quot;ws://&quot; + wssUrl + &quot;/ws&quot;;
    final WebSocketClient client = new WebSocketClient();
    final WSEventSocket socket = new WSEventSocket(loginRequest);
    try {
        client.start();

        final ClientUpgradeRequest request = new ClientUpgradeRequest();
        final URI wsUri = new URI(wsAddress);

        logger.info(&quot;Connecting to {}&quot;, wsUri);
        final Future&lt;Session&gt; session = client.connect(socket, wsUri, request);

        final String requestjson = mapper.writeValueAsString(wsRequestPojo);
        final Future&lt;Void&gt; fut = session.getRemote().sendStringByFuture(requestjson);
...

Javascript side snippet:

var wsRequestJson = {...Use output from Java Side...}
var mySock = new WebSocket(&quot;ws://&quot; + wsocketUrl + &quot;/ws&quot;);
mySock.onmessage = function(evt) { console.log(evt.data); }; mySock.onclose = function() { console.log(&quot;CLOSED&quot;); };
mySock.send(JSON.stringify(wsRequestJson));

The Javascript side works perfectly, the Java side is not encoding the data properly. I've tried abunch of things like JSON to byte array and such no luck. I Wiresharked both transactions and I see the WebSocket pushes and the Responses. In Java I'm seeing a Payload that looks exactly like JSON and Wireshark deciphers it. On the Javascript packets I see some type of encoded data \214P\311n\3020\024... I read a little bit about Masked Payloads and both clients are sending Masked Payloads with Masking-Keys, maybe something to do with that?

Any idea how to get the Java Jetty side to encode the data in a similar fashion? Or even what type of encoding the Javascript side is using? I'm probably over thinking it at this point...

Thanks!

答案1

得分: 0

如@Joakim Erdfelt在上面的评论中所述,Javascript端默认使用Sec-Websocket-Extension: permessage-deflate。这可能不是设置的最佳方式,但我通过添加以下Java代码来更新我的代码:

request.addExtensions(ExtensionConfig.parse("permessage-deflate"));

更新后的代码段:

final String wsAddress = "ws://" + wssUrl + "/ws";
final WebSocketClient client = new WebSocketClient();
final WSEventSocket socket = new WSEventSocket(loginRequest);
try {
    client.start();

    final ClientUpgradeRequest request = new ClientUpgradeRequest();
    request.addExtensions(ExtensionConfig.parse("permessage-deflate"));
    final URI wsUri = new URI(wsAddress);

    logger.info("Connecting to {}", wsUri);
    final Future<Session> session = client.connect(socket, wsUri, request);

    final String requestjson = mapper.writeValueAsString(wsRequestPojo);
    final Future<Void> fut = session.getRemote().sendStringByFuture(requestjson);
    ...

非常顺利地工作!谢谢!

英文:

As stated by @Joakim Erdfelt in a comment above the Javascript side is using Sec-Websocket-Extension: permessage-deflate by default. Might not be the best way to set it but I updated my Java code by adding:

request.addExtensions(ExtensionConfig.parse(&quot;permessage-deflate&quot;));

Updated Snippet:

final String wsAddress = &quot;ws://&quot; + wssUrl + &quot;/ws&quot;;
    final WebSocketClient client = new WebSocketClient();
    final WSEventSocket socket = new WSEventSocket(loginRequest);
    try {
        client.start();

        final ClientUpgradeRequest request = new ClientUpgradeRequest();
        request.addExtensions(ExtensionConfig.parse(&quot;permessage-deflate&quot;));
        final URI wsUri = new URI(wsAddress);

        logger.info(&quot;Connecting to {}&quot;, wsUri);
        final Future&lt;Session&gt; session = client.connect(socket, wsUri, request);

        final String requestjson = mapper.writeValueAsString(wsRequestPojo);
        final Future&lt;Void&gt; fut = session.getRemote().sendStringByFuture(requestjson);
...

Works like a charm! Thanks!

huangapple
  • 本文由 发表于 2020年4月8日 02:17:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/61086715.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定