libGDX:正确地在GWT中使用websocket

3

我已经努力了几天,试图使用Websockets进行基本的客户端/服务器通信。

我的客户端是一个带有libGDX的Java客户端,我的服务器是一个基本的Java服务器。

我的主要目标是将我的客户端编译成HTML5,以便使用Websockets与我的服务器通信。

当我在谷歌上搜索时,尝试了以下解决方案:

1似乎是最好的解决方案,但它没有TCP_NODELAY套接字设置(这在我的情况下非常重要)。

2也是另一个不错的解决方案,但它依赖于http://code.google.com/p/gwt-ws/(目前我不明白这一点)。

3是我选择的,一个简单的WebSocket Java API,让我非常容易地编写客户端和服务器。它在桌面和Android上运行得非常好,但当我尝试html:dist时,gradle会报websocket的错误,因为它没有继承等......

我的主build.gradle文件对每个项目(核心,桌面,Android,HTML)都包含此行:compile "org.java-websocket:Java-WebSocket:1.3.7"

因此,总结我的主要问题:如何在使用GWT编译的Ligdx客户端中正确建立带有TCP_NODELAY的WebSocket连接?

我的客户端只是一个非常简单的类:

package com.mygdx.game;
import java.net.URI;
import java.nio.ByteBuffer;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.handshake.ServerHandshake;

public class WebSocketsNet extends WebSocketClient {

    public WebSocketsNet(URI serverUri, Draft draft) {
        super(serverUri, draft);
    }

    public WebSocketsNet(URI serverURI) {
        super(serverURI);
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        send("Hello, it is me. Mario :)");
        System.out.println("new connection opened");
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        System.out.println("closed with exit code " + code + " additional info: " + reason);
    }

    @Override
    public void onMessage(String message) {
        System.out.println("received message: " + message);
    }

    @Override
    public void onMessage(ByteBuffer message) {
        System.out.println("received ByteBuffer");
    }

    @Override
    public void onError(Exception ex) {
        System.err.println("an error occurred:" + ex);
    }}

不幸的是,WebSockets相当有限,您无法像原始套接字那样对它们进行完全控制 - 浏览器控制大部分套接字设置,以防止发生各种攻击。这可能是其中之一 - 查看WebSocket规范和其他描述它的文档,以了解WebSocket设置中甚至可用的少数选项 https://developer.mozilla.org/en-US/docs/Web/API/WebSocket。另一方面,在服务器端更改此设置或其他设置是否足够,因为您在那里拥有更多控制权? - Colin Alworth
你好,感谢你的回答!我几天前刚看到了Mozilla网站。显然,我可以很容易地在服务器端禁用Nagle算法(例如:WebSocketServer server = new Server(new InetSocketAddress(host, port)); server.setTcpNoDelay(true);)。但是客户端是否也需要这样做呢?还是只有服务器端的TCP无延迟更重要? - War-sloop
2个回答

1

最终我找到了一种方法使它工作了,所以我在这里发布了一个答案,供那些感兴趣的人参考。

我使用了https://github.com/czyzby/gdx-lml/tree/master/websocket

特别是示例包,并严格遵循需要添加到build.gradle和不同xml文件中的所有内容,现在它已经可以工作了!

因此,总结一下:

  • 服务器使用java-web-socket监听websockets
  • LIBGDX客户端使用gdx-websockets连接到服务器(注意不同的build gradle文件和xml!!)

希望能帮助像我一样有同样问题的人!


1
根据https://bugs.webkit.org/show_bug.cgi?id=102079https://groups.google.com/forum/#!topic/native-client-discuss/T8zdrMjiTAE, 通过https://github.com/websockets/ws/issues/791https://github.com/varspool/Wrench/pull/104发现,大多数浏览器已经使用TCP_NODELAY。至少从websocket标准来看,您无法在客户端上影响此设置-在服务器上可能有更多选项。
如果已经在客户端设置了TCP_NODELAY,则可以在服务器上也进行设置,以确保双方都尽快发送小消息。

在类似https://dev59.com/SGYr5IYBdhLWcg3w0tWE#13406438的问题中提出的另一个想法是立即回复每个消息,以便网络堆栈尽快刷新所有剩余的消息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接