我尝试从spring站点运行此示例: 教程, 除了Spring Boot部分。
Web.xml
<web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>sample</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextClass</param-name> <param-value> org.springframework.web.context.support.AnnotationConfigWebApplicationContext </param-value> </init-param> <init-param> <param-name>contextConfigLocation</param-name> <param-value> com.evgeni.websock.WebSocketConfig </param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>sample</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
Java配置:
@Configuration @ComponentScan(basePackages = {"com.evgeni.controller"}) @EnableWebSocketMessageBroker @EnableWebMvc public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketMessageBrokerConfigurer { public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/hello").withSockJS(); } public void configureClientInboundChannel(ChannelRegistration registration) { // TODO Auto-generated method stub } public void configureClientOutboundChannel(ChannelRegistration registration) { // TODO Auto-generated method stub } public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/app"); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(31556926); registry.addResourceHandler("/img/**").addResourceLocations("/img/").setCachePeriod(31556926); registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926); } }
控制器:
@Controller public class GreetingController { @MessageMapping("/hello") @SendTo("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception { Thread.sleep(3000); // simulated delay System.out.println(message.getName()); return new Greeting("Hello, " + message.getName() + "!"); } }
index.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <title>Hello WebSocket</title> <script src="<c:url value='/js/sockjs-0.3.js'/>"></script> <script src="<c:url value='/js/stomp.js'/>"></script> <script type="text/javascript"> var stompClient = null; function setConnected(connected) { document.getElementById('connect').disabled = connected; document.getElementById('disconnect').disabled = !connected; document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden'; document.getElementById('response').innerHTML = ''; } function connect() { var socket = new SockJS("<c:url value='/hello'/>"); stompClient = Stomp.over(socket); stompClient.connect('', '', function(frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe("<c:url value='/topic/greetings'/>", function(greeting){ showGreeting(JSON.parse(greeting.body).content); }); }); } function disconnect() { stompClient.disconnect(); setConnected(false); console.log("Disconnected"); } function sendName() { var name = document.getElementById('name').value; stompClient.send("<c:url value='/app/hello'/>", {}, JSON.stringify({ 'name': name })); } function showGreeting(message) { var response = document.getElementById('response'); var p = document.createElement('p'); p.style.wordWrap = 'break-word'; p.appendChild(document.createTextNode(message)); response.appendChild(p); } </script> </head> <body> <noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!</h2></noscript> <div> <div> <button id="connect" onclick="connect();">Connect</button> <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button> </div> <div id="conversationDiv"> <label>What is your name?</label><input type="text" id="name" /> <button id="sendName" onclick="sendName();">Send</button> <p id="response"></p> </div> </div> </body> </html>
除了从web.xml和jsp中的2-3 c:url加载以添加项目根目录的配置文件之外,其他所有操作均与本教程相同。
当我单击连接然后发送时,在浏览器控制台中,我得到:
Opening Web Socket... stomp.js:122 Web Socket Opened... stomp.js:122 >>> CONNECT login: passcode: accept-version:1.1,1.0 heart-beat:10000,10000 stomp.js:122 <<< ERROR message:Illegal header\c 'login\c'. A header must be of the form <name>\c<value> content-length:0 stomp.js:122 >>> SEND destination:/websock/app/hello content-length:14 {"name":"asd"}
我认为这个问题在Sock js的connect函数中
stompClient.connect('', '', function(frame) {...
我正在传递“”作为登录名和密码。
编辑: 当我将连接功能更改stompClient.connect('random', 'random',为控制台中的响应时是:
stompClient.connect('random', 'random',
Opening Web Socket... stomp.js:122 Web Socket Opened... stomp.js:122 >>> CONNECT login:asd passcode:asd accept-version:1.1,1.0 heart-beat:10000,10000 stomp.js:122 <<< CONNECTED heart-beat:0,0 version:1.1 stomp.js:122 connected to server undefined stomp.js:122 Connected: CONNECTED version:1.1 heart-beat:0,0 (index):23 >>> SUBSCRIBE id:sub-0 destination:/websock/topic/greetings stomp.js:122 >>> SEND destination:/websock/app/hello content-length:14 {"name":"asd"}
但消息未传递到控制器。
错误是错误的控制器映射。我有:
@MessageMapping("/hello") @SendTo("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception
在jsp中:
stompClient.subscribe("<c:url value='/topic/greetings'/>", function(greeting){...
和
stompClient.send("<c:url value='/app/hello'/>", {}, JSON.stringify({ 'name': name }));
正确的是:
stompClient.subscribe('/topic/greetings', function(greeting){... stompClient.send('/app/hello', {}, JSON.stringify({ 'name': name }));
c:url添加了项目的根目录,当我将其删除时,该应用程序正常运行。但是,在此处使用SockJs创建新套接字时需要c:url(根目录):
var socket = new SockJS("<c:url value='/hello'/>");