从桌面应用程序访问 websocket

access websocket from a desktop application

我有一个带有 spring-websocket 的项目,此设置:

SocketHandler.java

@Component
public class SocketHandler extends TextWebSocketHandler {
    List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
        Map<String, String> value = new Gson().fromJson(message.getPayload(), Map.class);
        session.sendMessage(new TextMessage("Hello " + value.get("name") + " !"));
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
    }
}

WebSocketConfig.java

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new SocketHandler(), "/name");
    }
}

index.html

  <table>
    <tr>
      <td>
        <button id="connect" type="button" onclick="connect();">Connect</button>
        <button id="disconnect" type="button" disabled="disabled" onclick="disconnect();">Disconnect</button>
      </td>
      <td>
        <label for="name">What is your name?</label>
        <input type="text" id="name" placeholder="Your name here...">
        <button id="send" type="button" onclick="send();">Send</button>
      </td>
    </tr>
  </table>

  <hr>

  <table id="conversation" border="2">
      <thead>
      <tr>
          <th>Greetings</th>
      </tr>
      </thead>
      <tbody id="greetings">
      </tbody>
  </table>

script.js

var ws;

function setConnected(connected) {
    var connect = document.querySelector("#connect");
    var disconnect = document.querySelector("#disconnect");
    var conversation = document.querySelector("#conversation");
    var greetings = document.querySelector("#greetings");

    if(connected) {
      connect.setAttribute("disabled", "disabled");
      disconnect.removeAttribute("disabled");
      conversation.style.display = 'block';
    } else {
      connect.removeAttribute("disabled");
      disconnect.setAttribute("disabled", "disabled");
      conversation.style.display = 'none';
    }

    greetings.innerHTML = "";
}

function connect() {
    ws = new WebSocket('ws://localhost:8080/name');
    ws.onmessage = function(text) {
        showGreeting(text.data);
    }
    setConnected(true);
}

function disconnect() {
    if (ws != null) {
        ws.close();
    }
    setConnected(false);
}

function send() {
  var name = document.querySelector("#name");
    var data = JSON.stringify({'name': name.value});
  ws.send(data);
}

function showGreeting(message) {
  var greeting = document.querySelector("#greetings");
  var tr = document.createElement("tr");
  var td = document.createElement("td");
  td.innerText = message;
  tr.appendChild(td);
  greeting.appendChild(tr);
}

我想知道是否有可能开发一个桌面客户端应用程序,例如,使用 Java/Swing 或 C++/Qt,它可以像服务器一样与该应用程序通信,从桌面应用程序接收数据并广播给连接到它的所有客户端。

这是基于 Java 的 WebSocket 客户端的最小非 GUI 版本。


服务器

SocketHandler.java

import com.google.gson.Gson;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
public class SocketHandler extends TextWebSocketHandler {
    List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();

    @Override
    public void handleTextMessage(WebSocketSession currentSession, TextMessage message) throws InterruptedException, IOException {
        Map<String, String> value = new Gson().fromJson(message.getPayload(), Map.class);
        TextMessage textMessage = new TextMessage("Hello from " + value.get("name") + "!");

        for (WebSocketSession session : sessions) {
            if (session.isOpen()) {
                session.sendMessage(textMessage);
            }
        }
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
    }
}

客户

MyWebSocketClient.java

package com.example;

import java.net.URI;
import java.util.Scanner;
import javax.websocket.*;
import javax.websocket.RemoteEndpoint.Basic;

@ClientEndpoint
public class MyWebSocketClient {
    @OnMessage
    public void onMessage(String message) {
        System.out.println("[Greetings] " + message + "\n");
    }

    public static void main(String[] args) {
        WebSocketContainer container = null;
        Session session = null;
        Basic basicRemote = null;
        Scanner inputScanner = null;

        try {
            container = ContainerProvider.getWebSocketContainer();
            session = container.connectToServer(MyWebSocketClient.class, URI.create("ws://localhost:8080/name"));
            basicRemote = session.getBasicRemote();
            inputScanner = new Scanner(System.in);

            while (true) {
                String input = inputScanner.nextLine();
                basicRemote.sendText("{ \"name\": \"" + input + "\" }");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

pom.xml

<dependencies>
    <dependency>
        <groupId>javax.websocket</groupId>
        <artifactId>javax.websocket-client-api</artifactId>
        <version>1.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.tyrus.bundles</groupId>
        <artifactId>tyrus-standalone-client</artifactId>
        <version>1.15</version>
    </dependency>
</dependencies>

结果: