Search code examples
javaspringwebsocketspring-websocket

How to call the websocket server to sends the message to the client in spring


My project uses spring framework

WebSocketConfig.java

@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements  WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
         registry.addHandler(systemWebSocketHandler(),"/webSocketServer").addInterceptors(new   WebSocketHandshakeInterceptor());

         registry.addHandler(systemWebSocketHandler(), "/sockjs/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor())
            .withSockJS();
    }

    @Bean
    public WebSocketHandler systemWebSocketHandler(){
        return new SystemWebSocketHandler();
    }

}

SystemWebSocketHandler.java

public class SystemWebSocketHandler implements WebSocketHandler {

private static final Logger logger;

private static final ArrayList<WebSocketSession> users;

static {
    users = new ArrayList<>();
    logger = LoggerFactory.getLogger(SystemWebSocketHandler.class);
}

@Autowired
private WebSocketService webSocketService;

@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
    logger.debug("connect to the websocket success......");
    users.add(session);
    String userName = (String) session.getAttributes().get(Constants.WEBSOCKET_USERNAME);
    //查询未读消息
    int count = webSocketService.getUnReadNews((String)session.getAttributes().get(Constants.WEBSOCKET_USERNAME));

    session.sendMessage(new TextMessage(count+""));
}

@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {

}

@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
    logger.debug("websocket connection closed......");
    users.remove(session);
}

@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
    logger.debug("websocket connection closed......");
    users.remove(session);
}

@Override
public boolean supportsPartialMessages() {
    return false;
}

/**
 * 给所有在线用户发送消息
 *
 * @param message
 */
public void sendMessageToUsers(TextMessage message) {
    for (WebSocketSession user : users) {
        try {
            if (user.isOpen()) {
                user.sendMessage(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 给某个用户发送消息
 *
 * @param userName
 * @param message
 */
public void sendMessageToUser(String userName, TextMessage message) {
    for (WebSocketSession user : users) {
        if (user.getAttributes().get(Constants.WEBSOCKET_USERNAME).equals(userName)) {
            try {
                if (user.isOpen()) {
                    user.sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            break;
        }
    }
}
}

my jsp client

if ('WebSocket' in window) {
            websocket = new WebSocket("ws://localhost:8080/Origami/webSocketServer");
        } else if ('MozWebSocket' in window) {
            websocket = new MozWebSocket("ws://localhost:8080/Origami/webSocketServer");
        } else {
            websocket = new SockJS("http://localhost:8080/Origami/sockjs/webSocketServer");
        }

this is my websocket code and it works well

now I want to send messages to the client in a controller ,this is my controller

@Controller
public class AdminController {

static Logger logger = LoggerFactory.getLogger(AdminController.class);

@Autowired(required = false)
private AdminService adminService;

@Autowired(required = false)
private SystemWebSocketHandler systemWebSocketHandler;

@RequestMapping("/auditing")
@ResponseBody
public String auditing(HttpServletRequest request){
    String result = "fail";
    int id = Integer.parseInt(request.getParameter("id"));
    String reason = request.getParameter("reason");
    String title = request.getParameter("title");
    String username = request.getParameter("username");
    News news = new News();
    DateTime dateTime = DateTime.now();
    news.setNewsTime(dateTime.toDate());
    news.setState(0);
    news.setUsername(username);
    if(reason.equals("")){
        result = adminService.auditingById(id,"Y");
        news.setNewsContent(String.format(Constants.AUDIT_MESSAGE, username, title, reason));
        adminService.addNewsWithUnAudit(news);
    }else{
        news.setNewsContent(String.format(Constants.UN_AUDIT_MESSAGE,username,title,reason));
        result = adminService.addNewsWithUnAudit(news);
        result = adminService.auditingById(id, "D");
    }
    //SystemServerEndPoint serverEndPoint = new SystemServerEndPoint();
    int unReadNewsCount = adminService.getUnReadNews(username);
    systemWebSocketHandler.sendMessageToUser(username, new TextMessage(unReadNewsCount + ""));
    return result;
}
}

I want to call

systemWebSocketHandler.sendMessageToUser(username, new TextMessage(unReadNewsCount + ""));

to send message to the client but systemWebSocketHandler is null

How to inject the systemWebSocketHandler to the controller or some other ideas to complete the required? Such as the server connect to the websocketserver when it need to send message to the client and closed when it finished

My English is poor, but I'm trying to learn


Solution

  • I have resolved the problem

    @Controller
    public class AdminController {
    
    @Bean
    public SystemWebSocketHandler systemWebSocketHandler() {
        return new SystemWebSocketHandler();
    }