我是websocket的新手,在编写SpringBoot后端和angular前端之间的实时websocket通信方面有点吃力。用例非常简单,它是关于项目实时竞价的。所以我们的想法是有一些“房间”,我们想订阅新的信息。
我当前的websocket服务:
@Injectable({
providedIn: 'root'
})
export class WebSocketService {
connections: Array<ConnectionForHighestBid>;
RETRY_SECONDS = 10;
constructor() {
}
connect(itemId: number): Observable<any> {
return of('http://localhost:8090').pipe(
map(apiUrl => apiUrl.replace(/^http/, 'ws') + '/ws-item/' + itemId + '/highest-bid'),
switchMap(wsUrl => {
const connection = this.connections.filter(c => c.itemId === itemId);
// In case we already connected for given item id
if (connection && connection.length === 1) {
return connection[0].connection$;
} else {
const newConnection: ConnectionForHighestBid = {
itemId,
connection$: webSocket(wsUrl)
};
this.connections.push(newConnection);
return newConnection.connection$;
}
}),
retryWhen((errors) => errors.pipe(delay(this.RETRY_SECONDS)))
);
}
}
export interface ConnectionForHighestBid {
itemId: number;
connection$: WebSocketSubject<any>;
}
以及我正在执行以下操作的一个项的内部组件(this.itemid是我要订阅websocket通信的项的id:
this.webSockedService.connect(this.itemId).pipe(
takeUntil(this.destroyed$)
).subscribe(data => {
// Handle the newest data here (update price, add new bid item info, ...)
console.log(data);
});
后端正在使用spring boot websockets,目前有以下方法:
@MessageMapping("/ws-item/update/{itemId}")
@SendTo("/ws-item/{itemId}/highest-bid")
public ResponseEntity<ItemWsInfoResponse> getHighestBidDetail(@DestinationVariable("itemId") long itemId) {
return new ResponseEntity<>(itemService.findHighestBidByItemId(itemId), HttpStatus.OK);
}
@MessageMapping("/ws-item/bid/{itemId}")
@SendTo("/ws-item/{itemId}/highest-bid")
public ResponseEntity<ItemWsInfoResponse> bid(@DestinationVariable("itemId") long itemId,
@RequestBody @NonNull @Valid ItemWsBidRequest request) {
LocalDateTime currentTime =
LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.systemDefault());
Optional<ItemWsInfoResponse> bidOpt = itemService.bid(itemId, request, currentTime);
return bidOpt
.map(i -> new ResponseEntity<>(i, HttpStatus.OK))
.orElseGet(() -> new ResponseEntity<>(HttpStatus.BAD_REQUEST));
}
在这两种情况下,输出都是一个pojo,其中包含有关商品和当前最高出价的信息。其中第一种方法是获取当前信息。我不确定我是否需要那种方法。是否可以在websocket connect上执行此操作?如果我成功连接,我会得到这个pojo。
第二种方法是bidding本身(无需深入研究,方法只需检查并创建bid并返回pojo中的当前状态)。
配置如下
/**
* Websocket configuration
*
* Request URL: /ws-item
* Subscription URL: /ws-item/{itemId}
*/
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/ws-item");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-item").setAllowedOrigins("http://localhost:4200").withSockJS();
}
}
代码似乎还可以(或者,至少我正在“连接”到我的后端websocket层。但我真的不知道如何从前端执行投标行动。我想发送消息是要对给定的项目投标,是会做一些检查,如果成功的话,它会发送消息到“一般”池我订阅现在在那里我可以处理数据(更新项目价格,为新的出价添加新行,检查是否登录的用户当前中标等)。
所以问题是:如何在给定的连接上从fe执行bid操作(发送到bid be方法的数据现在可以是虚拟的和静态的,动态填充json是这里最小的问题)?有没有可能在连接后立即获得一些数据(所以我不需要称之为 /ws-item/update/{itemId}
连接成功后立即终止?
暂无答案!
目前还没有任何答案,快来回答吧!