我希望你的帮助,我已经看过了一切,但没有找到答案。任务是这样的:我需要从Java应用程序向客户端发送信息(frontend).信息的本质是用户在系统中有一个密码过期日期,我需要向用户发送一个通知,他的密码即将过期.当然,要做到这一点,我需要为一个特定的用户向数据库发出一个请求,计算他在密码过期前还有多少天。我想使用WebSocket来完成这个任务。我为训练视频和其他服务器和控制器做了一个配置类,但我仍然不明白我的应用程序应该如何向客户端发送信息。帮助!我已经考虑过使用@Sheduled注解,但是用这个注解标记的方法不能接受方法参数,那么我将无法为任何用户执行计时器请求。下面是我的代码,请告诉我!
WebSocketConfig类
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(final MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/ws");
}
@Override
public void registerStompEndpoints(final StompEndpointRegistry registry) {
registry.addEndpoint("/our-websocket")
.setHandshakeHandler(new UserHandshakeHandler())
.withSockJS();
}
}
字符串
UserHandshakeObject类
public class UserHandshakeHandler extends DefaultHandshakeHandler {
private final Logger LOG = LoggerFactory.getLogger(UserHandshakeHandler.class);
@Override
protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
final String randomId = UUID.randomUUID().toString();
LOG.info("User with ID '{}' opened the page", randomId);
return new UserPrincipal(randomId);
}
}
型
WSService类
@Service
public class WSService {
private final SimpMessagingTemplate messagingTemplate;
private final NotificationService notificationService;
@Autowired
public WSService(SimpMessagingTemplate messagingTemplate, NotificationService notificationService) {
this.messagingTemplate = messagingTemplate;
this.notificationService = notificationService;
}
public void notifyFrontend(final String message) {
ResponseMessage response = new ResponseMessage(message);
notificationService.sendGlobalNotification();
messagingTemplate.convertAndSend("/topic/messages", response);
}
public void notifyUser(final String id, final String message) {
ResponseMessage response = new ResponseMessage(message);
notificationService.sendPrivateNotification(id);
messagingTemplate.convertAndSendToUser(id, "/topic/private-messages", response);
}
}
型
WSController类
@RestController
public class WSController {
@Autowired
private WSService service;
@Autowired
private UsersRepository usersRepository;
@PostMapping("/send-message")
public void sendMessage(@RequestBody final Message message) {
service.notifyFrontend(message.getMessageContent());
}
@PostMapping("/send-private-message/{id}")
public void sendPrivateMessage(@PathVariable final String id,
@RequestBody final Message message) {
service.notifyUser(id, message.getMessageContent());
}
@Scheduled(fixedDelay = 10000)
public void sendPrivateMessage() {
List<Users> list = this.usersRepository.findAll();
for (Users users: list){
service.notifyUser(users.getId().toString(), "testString");
}
}
}
型
index.html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello WS</title>
<link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/sockjs-client/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/stomp.min.js"></script>
<script src="/scripts.js"></script>
</head>
<body>
<div class="container" style="margin-top: 50px">
<div class="row">
<div class="col-md-12">
<form class="form-inline">
<div class="form-group">
<label for="message">Message</label>
<input type="text" id="message" class="form-control" placeholder="Enter your message here...">
</div>
<button id="send" class="btn btn-default" type="button">Send</button>
</form>
</div>
</div>
<div class="row" style="margin-top: 10px">
<div class="col-md-12">
<form class="form-inline">
<div class="form-group">
<label for="private-message">Private Message</label>
<input type="text" id="private-message" class="form-control" placeholder="Enter your message here...">
</div>
<button id="send-private" class="btn btn-default" type="button">Send Private Message</button>
</form>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table id="message-history" class="table table-striped">
<thead>
<tr>
<th>Messages
<span
id="notifications"
style="
color: white;
background-color: red;
padding-left: 15px;
padding-right: 15px;">
</span>
</th>
</tr>
</thead>
<tbody id="messages">
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
型
script.js代码
var stompClient = null;
var notificationCount = 0;
$(document).ready(function() {
console.log("Index page is ready");
connect();
$("#send").click(function() {
sendMessage();
});
$("#send-private").click(function() {
sendPrivateMessage();
});
$("#notifications").click(function() {
resetNotificationCount();
});
});
function connect() {
var socket = new SockJS('/our-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
updateNotificationDisplay();
stompClient.subscribe('/topic/messages', function (message) {
showMessage(JSON.parse(message.body).content);
});
stompClient.subscribe('/user/topic/private-messages', function (message) {
showMessage(JSON.parse(message.body).content);
});
stompClient.subscribe('/topic/global-notifications', function (message) {
notificationCount = notificationCount + 1;
updateNotificationDisplay();
});
stompClient.subscribe('/user/topic/private-notifications', function (message) {
notificationCount = notificationCount + 1;
updateNotificationDisplay();
});
});
}
function showMessage(message) {
$("#messages").append("<tr><td>" + message + "</td></tr>");
}
function sendMessage() {
console.log("sending message");
stompClient.send("/ws/message", {}, JSON.stringify({'messageContent': $("#message").val()}));
}
function sendPrivateMessage() {
console.log("sending private message");
stompClient.send("/ws/private-message", {}, JSON.stringify({'messageContent': $("#private-message").val()}));
}
function updateNotificationDisplay() {
if (notificationCount == 0) {
$('#notifications').hide();
} else {
$('#notifications').show();
$('#notifications').text(notificationCount);
}
}
function resetNotificationCount() {
notificationCount = 0;
updateNotificationDisplay();
}
型
1条答案
按热度按时间0pizxfdo1#
如果您要使用WebSocket,您传送通知的使用者必须在此时使用此应用程序。也就是说,如果您传送通知的使用者未登入系统,他们就无法接收消息。因此,使用邮件服务器而非websocket会更符合逻辑。
如果您仍然想使用WebSocket,请同时分享客户端(前端)代码。在您可以向客户端发送信息之前,客户端必须连接到websocket。在成功建立连接之后,您必须订阅频道。
首先,WebSocketConfig类需要按如下方式进行编辑。
字符串
然后,您应该更正UseHandshakeHandler类别。您必须以下列方法存取并使用要求使用者的信息。
型
我在下面添加了一个html和js代码的例子。你可以用这个来测试。
源代码/主/资源/静态/应用程序.js:
型
来源/主要/资源/静态/索引.html:
型
现在,运行该应用程序并打开
index.html
文件。按下连接按钮,并从 Postman 向屏幕上显示的user-name
值发送请求。您将看到该消息到达用户。测试图片。
connect to websocket
send message to user by id的
show message的