5

我正在尝试在同一台 Android 设备上同时实现 WebSocket 客户端和 WebSocket 服务器。基本上我有两个需要通信的 Android 应用程序。我已经成功地使用 LocalSockets 实现了几个测试应用程序,但是目标客户端应用程序是 Web 浏览器应用程序,因此它只能使用 WebSockets。

我已经尝试过https://github.com/TooTallNate/Java-WebSocket实现。我让客户端应用程序在前台运行,服务器应用程序在后台运行在 Android 服务中。本质上,我采用了有效的 LocalSocket 实现,并用 TooTallNate 的 WebSockets 替换了 LocalSockets。WebSocket 服务器似乎无法启动。明显的症状是客户端每次尝试发送内容时都会抛出 NotYetConnectedException。

另一个症状是,如果我尝试使用 WebSocketServer.run() 而不是 WebSocketServer.start(),我会从 ServerSocketChannel.open() 获得 IOException。

在这一点上,当然欢迎任何想法。谢谢!

4

2 回答 2

1

一个基本的实现是这样的:

public class ChatServer extends WebSocketServer
{
    private final String TAG = LogHelper.makeLogTag(ChatServer.class);

    private Map<String, WebSocket> clients = new ConcurrentHashMap<>();

    public ChatServer(int port)
    {
        super(new InetSocketAddress(port));
    }

    public ChatServer(InetSocketAddress address)
    {
        super(address);
    }

    @Override
    public void onOpen(WebSocket conn, ClientHandshake handshake) {
        String uniqueID = UUID.randomUUID().toString();
        clients.put(uniqueID, conn);

        conn.send(WrapHelper.regToJson(uniqueID));
        conn.send(WrapHelper.resToJson("Welcome to the server!"));


        broadcast((WrapHelper.resToJson("new connection: " + handshake.getResourceDescriptor()))); //This method sends a message to all clients connected
        LogHelper.e(TAG, conn.getRemoteSocketAddress().getAddress().getHostAddress() + " entered the room!");
    }

    @Override
    public void onClose(WebSocket conn, int code, String reason, boolean remote) {
        broadcast(WrapHelper.resToJson(conn + " has left the room!"));
        LogHelper.e(TAG, conn + " has left the room!");
    }

    @Override
    public void onMessage(WebSocket conn, String message) {
        Gson gson = new Gson();
        final Frame frame = gson.fromJson(message, Frame.class);
        if (frame != null) {
            LogHelper.e(TAG, "frame: " + frame);

            switch (frame.getCmd()) {
                case CMD_MSG:
                    broadcast(message);

                    break;

                case CMD_REG_USER:

                    break;
            }
        }
        LogHelper.e(TAG, conn + ": " + message);
    }

    @Override
    public void onMessage(WebSocket conn, ByteBuffer message) {
        broadcast(message.array());
        LogHelper.e(TAG, conn + ": " + message);
    }

    @Override
    public void onError(WebSocket conn, Exception ex)
    {
        ex.printStackTrace();
        if (conn != null) {
            // some errors like port binding failed may not be assignable to a specific websocket
        }
    }

    @Override
    public void onStart()
    {
        LogHelper.e(TAG, "Server started!");
        setConnectionLostTimeout(0);
        setConnectionLostTimeout(100);
    }
}

在此示例中,您可以看到我们正在覆盖WebSocketServer类的抽象方法。您可以创建一个界面来更新您的 UI。

然后在您的主要活动中,您可以像这样使用它:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    ...

    ChatServer server = new ChatServer(DEFAULT_CHAT_PORT);
    server.start();

    ...
}

我在这里有一个完整的聊天示例。

于 2018-08-21T04:00:54.853 回答
0

试试适用于 Android 的 WebSocket 和 Socket.io? https://github.com/koush/android-websockets

于 2013-05-19T20:05:12.723 回答