如何使用 Angular 9 收听 Quarkus Websocket?
How can I listen to a Quarkus Websocket using Angular 9?
如问题所示,我想构建一个服务,使用 Websocket
在用户之间同步 JSON 数据。但是我对 websockets
很陌生,所以我需要你的帮助。
我使用以下版本:
前端:
Angular: 9.1.0
后端:
Quarkus:1.3.2.Final + Quarkus-undertow-websockets
我在 Angular 服务中有以下代码:
import {Injectable} from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class SocketService {
private ws: any;
constructor() {
}
public connect(): void {
this.ws = new WebSocket('ws://localhost:8080/sync/breit');
this.ws.onmessage = (msg) => {
console.log(msg);
};
}
public sendData(data: any): void {
this.ws.send('/' + name, {}, 'Testmessage');
}
}
按下按钮时,函数连接在 ngOninit()
和 sendData()
中被调用。
现在,这是后端代码:
package io.sync.websocket;
import org.jboss.logging.Logger;
import javax.enterprise.context.ApplicationScoped;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint("/sync/{username}")
@ApplicationScoped
public class SyncSocket {
private static final Logger LOG = Logger.getLogger(SyncSocket.class);
Map<String, Session> sessions = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("username") String username) {
sessions.put(username, session);
}
@OnClose
public void onClose(Session session, @PathParam("username") String username) {
sessions.remove(username);
}
@OnError
public void onError(Session session, @PathParam("username") String username, Throwable throwable) {
sessions.remove(username);
LOG.error("onError", throwable);
}
@OnMessage
public void onMessage(String message, @PathParam("username") String username) {
System.out.println("Message came through");
broadcast(message);
}
private void broadcast(String message) {
sessions.values().forEach(s -> {
s.getAsyncRemote().sendObject(message, result -> {
if (result.getException() != null) {
System.out.println("Unable to send message: " + result.getException());
}
});
});
}
}
我从 Quarkus Websocket 教程中获得了这段代码。稍微修改了一下。
现在,当我按下调用服务中的 sendData()
函数的发送按钮时,我希望收到 Testmessage
,但我只收到 /
:
网络控制台中的输出:
我不知道如何向 Quarkus 添加额外的 "listener" URL,我可以只定义 ServerEndpoint。在 Spring 引导中,它将是 @SendTo('URL_COMES_HERE')
注释。 Quarkus 中是否存在这样的东西?
请检查您的 sendData 方法。我认为数据的行为是“/”是预期的。
"name" 来自哪里?此时它似乎只是一个空字符串。
另外,关于"Testmessage":如果查看Websocket.send方法,你会发现该方法只有一个参数;所以 "Testmessage" 参数将被忽略。
如问题所示,我想构建一个服务,使用 Websocket
在用户之间同步 JSON 数据。但是我对 websockets
很陌生,所以我需要你的帮助。
我使用以下版本:
前端: Angular: 9.1.0
后端: Quarkus:1.3.2.Final + Quarkus-undertow-websockets
我在 Angular 服务中有以下代码:
import {Injectable} from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class SocketService {
private ws: any;
constructor() {
}
public connect(): void {
this.ws = new WebSocket('ws://localhost:8080/sync/breit');
this.ws.onmessage = (msg) => {
console.log(msg);
};
}
public sendData(data: any): void {
this.ws.send('/' + name, {}, 'Testmessage');
}
}
按下按钮时,函数连接在 ngOninit()
和 sendData()
中被调用。
现在,这是后端代码:
package io.sync.websocket;
import org.jboss.logging.Logger;
import javax.enterprise.context.ApplicationScoped;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint("/sync/{username}")
@ApplicationScoped
public class SyncSocket {
private static final Logger LOG = Logger.getLogger(SyncSocket.class);
Map<String, Session> sessions = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("username") String username) {
sessions.put(username, session);
}
@OnClose
public void onClose(Session session, @PathParam("username") String username) {
sessions.remove(username);
}
@OnError
public void onError(Session session, @PathParam("username") String username, Throwable throwable) {
sessions.remove(username);
LOG.error("onError", throwable);
}
@OnMessage
public void onMessage(String message, @PathParam("username") String username) {
System.out.println("Message came through");
broadcast(message);
}
private void broadcast(String message) {
sessions.values().forEach(s -> {
s.getAsyncRemote().sendObject(message, result -> {
if (result.getException() != null) {
System.out.println("Unable to send message: " + result.getException());
}
});
});
}
}
我从 Quarkus Websocket 教程中获得了这段代码。稍微修改了一下。
现在,当我按下调用服务中的 sendData()
函数的发送按钮时,我希望收到 Testmessage
,但我只收到 /
:
网络控制台中的输出:
我不知道如何向 Quarkus 添加额外的 "listener" URL,我可以只定义 ServerEndpoint。在 Spring 引导中,它将是 @SendTo('URL_COMES_HERE')
注释。 Quarkus 中是否存在这样的东西?
请检查您的 sendData 方法。我认为数据的行为是“/”是预期的。 "name" 来自哪里?此时它似乎只是一个空字符串。 另外,关于"Testmessage":如果查看Websocket.send方法,你会发现该方法只有一个参数;所以 "Testmessage" 参数将被忽略。