依賴
//javaee support
compile 'javax.servlet:javax.servlet-api:3.1.0'
compile 'javax.servlet:jstl:1.2'
compile 'javax.inject:javax.inject:1'
compile 'javax:javaee-api:7.0'
compile 'io.netty:netty-all:4.1.2.Final'
// web server
providedCompile 'org.eclipse.jetty:jetty-webapp:9.2.2.v20140723'
providedCompile 'org.eclipse.jetty:jetty-jsp:9.2.2.v20140723'
providedCompile 'org.eclipse.jetty:jetty-continuation:9.2.2.v20140723'
providedCompile 'org.eclipse.jetty.websocket:websocket-server:9.2.2.v20140723'
相關websocket代碼
package org.nlpcn.jcoder.util.websocket;
import javax.websocket.server.ServerEndpointConfig;
import org.nutz.mvc.Mvcs;
public class WebSocketConfigurator extends ServerEndpointConfig.Configurator {
public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
return Mvcs.ctx().getDefaultIoc().get(endpointClass);
}
}
package org.nlpcn.jcoder.util.websocket;
import java.io.IOException;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WebSocketStringHandler implements MessageHandler.Whole<String> {
private static final Logger LOG = LoggerFactory.getLogger(WebSocketConfigurator.class) ;
protected Session session;
public WebSocketStringHandler(String uu32, Session session) {
this.session = session;
}
public Session getSession() {
return session;
}
public void depose() {
try {
LOG.info(session.getId()+" exit");
session.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onMessage(String message) {
LOG.info(session.getId()+" send message : "+message);
}
}
package org.nlpcn.jcoder.service;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.CloseReason;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.nlpcn.jcoder.util.websocket.WebSocketConfigurator;
import org.nlpcn.jcoder.util.websocket.WebSocketStringHandler;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.random.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//@Filters(@By(type = AuthoritiesManager.class, args = { "userType", "1", "/login.jsp" }))
@ServerEndpoint(value = "/console", configurator = WebSocketConfigurator.class)
@IocBean(create = "init", depose = "depose")
public class WebsocketService extends Endpoint {
protected static final Logger LOG = LoggerFactory.getLogger(WebsocketService.class);
protected ConcurrentHashMap<String, WebSocketStringHandler> _sessions = new ConcurrentHashMap<>();
protected ConcurrentHashMap<String, String> sessionIds = new ConcurrentHashMap<String, String>();
public void init() {
LOG.info("websocket service starting");
}
/**
* send all message for online client
*
* @param message
*/
public void sendMessage(final String message) {
_sessions.entrySet().parallelStream().forEach(e -> {
WebSocketStringHandler handler = e.getValue();
if (handler.getSession().isOpen()) {
handler.getSession().getAsyncRemote().sendText(message);
}
});
}
public void onMessage(String channel, String message) {
LOG.info(channel + ":" + message);
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
String uu32 = sessionIds.remove(session.getId());
if (uu32 == null)
return;
WebSocketStringHandler handler = _sessions.remove(uu32);
if (handler != null)
handler.depose();
}
@OnError
public void onError(Session session, java.lang.Throwable throwable) {
onClose(session, null);
}
@OnOpen
public void onOpen(Session session, EndpointConfig config) {
String uu32 = R.UU32();
WebSocketStringHandler handler = new WebSocketStringHandler(uu32, session);
session.addMessageHandler(handler);
sessionIds.put(session.getId(), uu32);
_sessions.put(uu32, handler);
}
@OnMessage
public void onMessage(String message, Session session) {
WebSocketStringHandler handler = getHandler(session.getId());
if (handler != null)
handler.onMessage(message);
}
protected WebSocketStringHandler getHandler(String sessionId) {
String uu32 = sessionIds.get(sessionId);
if (uu32 == null)
return null;
return _sessions.get(uu32);
}
public void depose() {
}
public int count() {
return _sessions.size();
}
}
通過
var ws = new WebSocket("ws://localhost:8080/console");
報
WebSocket connection to 'ws://localhost:8080/console' failed: WebSocket opening handshake timed out
debug
public boolean handle(HttpServletRequest req, HttpServletResponse resp) {
ActionContext ac = new ActionContext();
ac.setRequest(req).setResponse(resp).setServletContext(config.getServletContext());
Mvcs.setActionContext(ac);
ActionInvoker invoker = mapping.get(ac); //這裏取到的是null。
if (null == invoker)
return false;
return invoker.invoke(ac);
}
日志
org.quartz.core.QuartzSchedulerThread-492846 DEBUG [2016-11-09 21:59:12] batch acquisition of 0 triggers
org.eclipse.jetty.io.IdleTimeout-500985 DEBUG [2016-11-09 21:59:20] SelectChannelEndPoint@2b0ba818{/0:0:0:0:0:0:0:1:55288<->8080,Open,in,out,-,-,30000,HttpConnection}{io=0,kio=0,kro=1} idle timeout check, elapsed: 30002 ms, remaining: -2 ms
org.eclipse.jetty.io.IdleTimeout-500985 DEBUG [2016-11-09 21:59:20] SelectChannelEndPoint@2b0ba818{/0:0:0:0:0:0:0:1:55288<->8080,Open,in,out,-,-,30000,HttpConnection}{io=0,kio=0,kro=1} idle timeout expired
org.eclipse.jetty.io.WriteFlusher-500985 DEBUG [2016-11-09 21:59:20] ignored: WriteFlusher@66c4ec6e{IDLE} {}
org.eclipse.jetty.io.AbstractEndPoint-500986 DEBUG [2016-11-09 21:59:20] Ignored idle endpoint SelectChannelEndPoint@2b0ba818{/0:0:0:0:0:0:0:1:55288<->8080,Open,in,out,-,-,30000,HttpConnection}{io=0,kio=0,kro=1}
org.nlpcn.jcoder.job.PrintConsoleJob-507569 DEBUG [2016-11-09 21:59:26] no connect ! wait for client conn!
org.eclipse.jetty.server.session-510624 DEBUG [2016-11-09 21:59:29] Scavenging sessions at 1478699969862
org.eclipse.jetty.server.session-510887 DEBUG [2016-11-09 21:59:30] Scavenging sessions at 1478699970125
org.quartz.core.QuartzSchedulerThread-521352 DEBUG [2016-11-09 21:59:40] batch acquisition of 0 triggers
org.eclipse.jetty.io.IdleTimeout-530988 DEBUG [2016-11-09 21:59:50] SelectChannelEndPoint@2b0ba818{/0:0:0:0:0:0:0:1:55288<->8080,Open,in,out,-,-,30000,HttpConnection}{io=0,kio=0,kro=1} idle timeout check, elapsed: 30002 ms, remaining: -2 ms
org.eclipse.jetty.io.IdleTimeout-530988 DEBUG [2016-11-09 21:59:50] SelectChannelEndPoint@2b0ba818{/0:0:0:0:0:0:0:1:55288<->8080,Open,in,out,-,-,30000,HttpConnection}{io=0,kio=0,kro=1} idle timeout expired
org.eclipse.jetty.io.WriteFlusher-530988 DEBUG [2016-11-09 21:59:50] ignored: WriteFlusher@66c4ec6e{IDLE} {}
org.eclipse.jetty.io.AbstractEndPoint-530989 DEBUG [2016-11-09 21:59:50] Ignored idle endpoint SelectChannelEndPoint@2b0ba818{/0:0:0:0:0:0:0:1:55288<->8080,Open,in,out,-,-,30000,HttpConnection}{io=0,kio=0,kro=1}
org.eclipse.jetty.server.session-540625 DEBUG [2016-11-09 21:59:59] Scavenging sessions at 1478699999863
org.eclipse.jetty.server.session-540888 DEBUG [2016-11-09 22:00:00] Scavenging sessions at 1478700000126
org.nlpcn.jcoder.job.CheckTaskJob-547650 DEBUG [2016-11-09 22:00:06] begin checkTaskJob
org.nutz.dao.impl.sql.run.NutDaoExecutor-547651 DEBUG [2016-11-09 22:00:06] SELECT * FROM task ORDER BY id DESC
org.quartz.core.QuartzSchedulerThread-550664 DEBUG [2016-11-09 22:00:09] batch acquisition of 0 triggers
org.eclipse.jetty.io.IdleTimeout-560991 DEBUG [2016-11-09 22:00:20] SelectChannelEndPoint@2b0ba818{/0:0:0:0:0:0:0:1:55288<->8080,Open,in,out,-,-,30000,HttpConnection}{io=0,kio=0,kro=1} idle timeout check, elapsed: 30002 ms, remaining: -2 ms
org.eclipse.jetty.io.IdleTimeout-560991 DEBUG [2016-11-09 22:00:20] SelectChannelEndPoint@2b0ba818{/0:0:0:0:0:0:0:1:55288<->8080,Open,in,out,-,-,30000,HttpConnection}{io=0,kio=0,kro=1} idle timeout expired
org.eclipse.jetty.io.WriteFlusher-560991 DEBUG [2016-11-09 22:00:20] ignored: WriteFlusher@66c4ec6e{IDLE} {}
org.eclipse.jetty.io.AbstractEndPoint-560992 DEBUG [2016-11-09 22:00:20] Ignored idle endpoint SelectChannelEndPoint@2b0ba818{/0:0:0:0:0:0:0:1:55288<->8080,Open,in,out,-,-,30000,HttpConnection}{io=0,kio=0,kro=1}
org.nlpcn.jcoder.job.PrintConsoleJob-569601 DEBUG [2016-11-09 22:00:28] no connect ! wait for client conn!
org.eclipse.jetty.server.session-570625 DEBUG [2016-11-09 22:00:29] Scavenging sessions at 1478700029863
org.eclipse.jetty.server.session-570889 DEBUG [2016-11-09 22:00:30] Scavenging sessions at 1478700030127
org.quartz.core.QuartzSchedulerThread-575631 DEBUG [2016-11-09 22:00:34] batch acquisition of 0 triggers