@Controller @Scope("session") public class ClientManagerController { @Autowired private ClientManager clientManager; @RequestMapping(value = "/init", method = RequestMethod.POST) @ResponseBody private String initializeClientManager(HttpSession session) { JSONObject result = new JSONObject(); try{ boolean loged = ClientManagersStorage.checkClientManager(clientManager, session) ; result.put("loged", loged); result.put("clientManagerId", clientManager.getId()); }catch(Throwable th){ result.put("error", th.toString()); } return result.toString(); }
public class ClientManagersStorage { final static private Map<String, ClientManager> clientManagers = new ConcurrentHashMap <String, ClientManager>(); public static boolean checkClientManager(ClientManager clientManager, HttpSession session) { ClientManager registeredClientManager = clientManagers.get(clientManager.getId()); if (registeredClientManager == null) { clientManager.setSession(session); addClientManager(clientManager); registeredClientManager = clientManager; } return registeredClientManager.getUser() != null; } ... }
@Override protected StreamInbound createWebSocketInbound(String paramString, HttpServletRequest request) { String clientManagerId = request.getParameter("clientManagerId"); ClientManager clientManager = ClientManagersStorage.findClientManager(clientManagerId); if(clientManager == null){ return new WebSocketConnection(null); } log.debug("new connection"); return new WebSocketConnection(clientManager); }
@Override protected void onOpen(WsOutbound outbound) { if(clientManager != null){ clientManager.addConnection(this); } }
@Override protected void onTextMessage(CharBuffer message) throws IOException { try { String connectionId = String.valueOf(this.hashCode()); String request = message.toString(); clientManager.handleClientRequest(request, connectionId); } catch (Throwable th) { log.error("in onTextMessage: " + th); } }
@Autowired private RequestHandler requestHandler; public void handleClientRequest(String request, String connectionId) { log.debug("handleClientRequest request=" + request); log.debug("handleClientRequest user=" + getUser()); /** handleRequest - never throws exceptions ! */ JSONObject response = requestHandler.handleRequest(request, this); String responseJson = response.toString(); CharBuffer buffer = CharBuffer.wrap(responseJson); WebSocketConnection connection = connections.get(connectionId); try { connection.getWsOutbound().writeTextMessage(buffer); } catch (IOException ioe) { log.error("in handleClientRequest: in writeTextMessage: " + ioe); } }
public class ClientManager{ public void setSession(HttpSession session) { /** session will be invalidated at connection removing */ session.setMaxInactiveInterval(Integer.MAX_VALUE);//69.04204112011317 years this.session = session; new Thread(new Runnable() { @Override public void run() { /** Giving time to client, for establish websocket connection. */ try {Thread.sleep(60000);} catch (InterruptedException ignored) {} /** if client not connected via websocket until this time - it is bot */ if (connections.size() == 0) {removeMe();} } }).start(); } private void removeMe() {ClientManagersStorage.removeClientManager(this);} ... }
public class WebSocketConnection{ @Override protected void onClose(int status) { if(clientManager != null){ clientManager.removeConnection(this); } } ... } public class ClientManager{ public void removeConnection(WebSocketConnection webSocketConnection) { String connectionId = getObjectHash(webSocketConnection); connections.remove(connectionId); if (connections.size() == 0) { log.debug("removeConnection before wait: connections.size()=" + connections.size()); /** may be client just reload page? */ try {Thread.sleep(waitForReloadTime);} catch (Throwable ignored) {} if (connections.size() == 0) { /** no, client leave us (page closed in browser)*/ ClientManagersStorage.removeClientManager(this); log.debug("client " + getId() + " disconnected"); } } } ... }
public static void removeClientManager(ClientManager clientManager) { ClientManager removed = clientManagers.remove(clientManager.getId()); if(removed == null){return;} User user = removed.getUser(); if(user != null){ Broadcaster.broadcastCommand("userPanel.setLogedCount", UserService.logedCount.decrementAndGet()); } Broadcaster.broadcastCommand("userPanel.setOnlineCount", ClientManagersStorage.getClientManagersCount()); try { clientManager.getSession().invalidate(); clientManager.setSession(null); } catch (Throwable th) { log.error("at removeClientManager: " + th); } }
public class Broadcaster{ public static void broadcastCommand(String method, Object params) { for (ClientManager clientManager : ClientManagersStorage.getClientManagers().values()) { clientManager.sendCommandToClient(method, params); } } public static void sendCommandToUser(Long userId, String method, Object params) { List<ClientManager> userClientManagers = ClientManagersStorage.findUserClientManagers(userId); for(ClientManager clientManager: userClientManagers){ clientManager.sendCommandToClient(method, params); } } }
public void sendCommandToClient(String method, Object params) { for(WebSocketConnection connection: connections.values()){ sendCommandToClientConnection(connection, method, params); } } private void sendCommandToClientConnection(WebSocketConnection connection, String method, Object params) { JSONObject commandBody = new JSONObject(); if(params == null){params = new JSONObject();} commandBody.put("method", method); commandBody.put("params", params); CharBuffer buffer = CharBuffer.wrap(commandBody.toString()); try { connection.getWsOutbound().writeTextMessage(buffer); } catch (IOException ioe) { log.error("in sendCommandToClient: in writeTextMessage: " + ioe); } }
var appName = "jrspc-ws"; var secured = document.location.protocol == "https:" ? "s" : ""; var HttpSessionInitializer = {url: "http"+secured+"://"+ document.location.host +"/"+appName+"/init"}; /** called from root-controller.js after its initialization */ HttpSessionInitializer.init = function($http) { $http.post(this.url, "").success(function(response){ if (response.error) { error(response.error); } else { loged = response.loged; Server.initialize("ws"+secured+"://"+ document.location.host +"/"+appName+"/ws?clientManagerId="+response.clientManagerId); if(loged){Listeners.notify("onLogin");} } }).error(function() {error("network error!");}); }
connector.initialize = function(url) { connector.url = url; try { connector.connect(url); return true; } catch (ex) { p("in connector.initialize: " + ex); return false; } }
Server.socketRequests = {}; var requestId = 0; function sendSocket(service, method, params, successCallback, errorCallback, control) { if (!checkSocket()) {return;} requestId++; if(!params){params = [];} if(!isArray(params)){params = [params];} var data = { service : service, method : method, params : params, requestId : requestId }; Server.socketRequests["request_" + requestId] = { successCallback : successCallback, errorCallback : errorCallback, control : control }; if (control) {control.disabled = true;} var message = JSON.stringify(data); log("sendSocket: "+message); connector.socket.send(message); } ... Server.call = sendSocket;
connector.socket.onmessage = function(message) { var data = message.data; var response = JSON.parse(data); var requestId = response.requestId; if (requestId) {/** server return response */ var control = Server.socketRequests["request_" + requestId].control; if (control) {control.disabled = false;} if (response.error) { var errorCallback = Server.socketRequests["request_" + requestId].errorCallback; if (errorCallback) { try { errorCallback(response.error); } catch (ex) { error("in connector.socket.onmessage errorCallback: " + ex + ", data=" + data); } }else{ error(response.error); } } else { var successCallback = Server.socketRequests["request_" + requestId].successCallback; if (successCallback) { try { successCallback(response.result); } catch (ex) { error("in connector.socket.onmessage successCallback: " + ex + ", data=" + data); } } } delete Server.socketRequests["request_" + requestId]; } else { /** server call client or broadcast */ var method = eval(response.method); var params = response.params; try { method(params); } catch (ex) { error("in connector.socket.onmessage call method: " + ex + ", data=" + data); } } };
self.sendMessage = function(command){ var message = {to: (self.sendPrivate ? self.privateTo : "all"), from: userPanel.user.login, text: self.newMessage, clientTime: new Date().getTime()}; Server.call("chatService", "dispatchMessage", message, function(){ self.newMessage = ""; self.$digest(); }, function(error){self.onError(error);}, command); } /** called from server */ self.onChatMessage = function (message){ message.isPrivate = (message.to != "all"); self.messages.push(message); self.$digest(); chatConsole.scrollTop = chatConsole.clientHeight + chatConsole.scrollHeight; }
@Component public class ChatService extends AbstractService{ @Autowired private UserManager userManager; @Secured("User") @Remote public void dispatchMessage(ChatMessage message){ message.setServerTime(new Date().getTime()); String to = message.getTo(); if("ALL".equalsIgnoreCase(to)){ Broadcaster.broadcastCommand("chatPanel.onChatMessage", message); }else{ User fromUser = getUser(); message.setFrom(fromUser.getLogin()); User toUser = userManager.findByLogin(to); if(toUser == null){throw new RuntimeException("User "+to+" not found!");} Broadcaster.sendCommandToUser(toUser.getId(), "chatPanel.onChatMessage", message); Broadcaster.sendCommandToUser(fromUser.getId(), "chatPanel.onChatMessage", message); } } }
function testController($scope){ var self = $scope; self.maxIterations = 1000; self.testIterations = self.maxIterations; self.testStart = 0; self.testEnd = 0; self.testForSpeedSerial = function(command){ if(self.testStart == 0){self.testStart = now();} if(--self.testIterations <= 0){ var duration = now() - self.testStart; alert("testForSpeedSerial duration="+duration); self.testStart = 0; self.testIterations = self.maxIterations; return; } Server.call("userService", "testForSpeed", "", function(){ self.testForSpeedSerial(command); }, error, command); } self.testForSpeedParallelResponses = 0; self.testForSpeedParallel = function(command){ self.testStart = now(); for(var i = 0; i < self.testIterations; i++){ Server.call("userService", "testForSpeed", "", function(){ self.testForSpeedParallelResponses++ ; if(self.testForSpeedParallelResponses >= self.maxIterations){ var duration = now() - self.testStart; alert("testForSpeedParallel duration="+duration); self.testForSpeedParallelResponses = 0; } }, error, command); } } }
@Remote public void testForSpeed(){}
Source: https://habr.com/ru/post/220015/
All Articles