江门官网建站公司,发布新闻的平台有哪些,我朋友是做卖网站的,电脑有网但浏览器打不开网页本博文#xff0c;保证不用装B的话语和太多专业的语言#xff0c;保证简单易懂#xff0c;只要懂JAVAEE开发的人都可以看懂。 本博文发表目的是#xff0c;目前网上针对Websocket的资料太散乱#xff0c;导致初学者的知识体系零零散散#xff0c;学习困难加大。本博加以整…本博文保证不用装B的话语和太多专业的语言保证简单易懂只要懂JAVAEE开发的人都可以看懂。 本博文发表目的是目前网上针对Websocket的资料太散乱导致初学者的知识体系零零散散学习困难加大。本博加以整理并且实践。所用核心技术选型Tomcat Spring 4.0.3 Mongodb(高并发数据库) SpringQueue(消息队列) ActiveMQ (消息队列) Spring-data-Mongo Servlet 3.0Spring-Websocket Maven注以下Websocket 均省略成 WB先说Websocket 的原理。 Websocket 是全双工通讯(说白了就是俩都可以通讯服务器也可以给客户端发消息客户端也能给服务器发消息)。也是基于TCP的效率是很高的首先这个技术的底层选用就决定了完全可以用wb这个技术做高并发应用而且开发非常快代码非常简单最重要的是稳定性扩展性等等都有保证等会儿说为什么说都有保证。WB 不同于TCP的三次握手。 WB是先进行一次HTTP请求这个请求头不同于普通HTTP请求等会贴出来讲解。然后服务器开始辨认请求头如果是WB的请求头则开始进行普通的TCP连接即三次握手(不懂的TCP的出门百度)。如果不是WB的HTTP请求头那就是按普通的HTTP请求处理。流程梳理 HTTP特殊请求(有个特殊的头) ---- 》 服务请接收判断 ----- 》 认出来了确实是WB请求头开启TCP 三次握手建立连接后和TCP一样了就------》没有认出来不是WB的请求头按普通HTTP请求处理。很清楚了吧。这是个基础先理解了下面写程序才好搞。下面这段是Webscoket的请求头。 GET请求GET ws://localhost:12345/websocket/test.html HTTP/1.1Origin: http://localhostConnection: UpgradeHost: localhost:12345Sec-WebSocket-Key: JspZdPxs9MrWCt3j6h7KdQ //主要这个字段这个叫“梦幻字符串”这个加密规则可以去百度是有规则的。这个也是个密钥只有有这个密钥 服务器才能通过解码 认出来哦~这是个WB的请求我要建立TCP连接了如果这个字符串没有按照加密规则加密那服务端就认不出来就会认为这整个协议就是个HTTP请求。更不会开TCP。其他的字段都可以随便设置但是这个字段是最重要的字段标识WB协议的一个字段。Upgrade: websocketSec-WebSocket-Version: 13下面这段是服务端回应消息HTTP/1.1 101 Web Socket Protocol HandshakeWebSocket-Location: ws://localhost:12345/websocket/test.phpConnection: UpgradeUpgrade: websocketSec-WebSocket-Accept: zUyzbJdkVJjhhu8KiAUCDmHtY/o //这个字段叫“梦幻字符串”和上面那个梦幻字符串作用一样。不同的是这个字符串是要让客户端辨认的客户端拿到后自动解码。并且辨认是不是一个WB请求。然后进行相应的操作。这个字段也是重中之重不可随便修改的。加密规则依然是有规则的可以去百度一下。WebSocket-Origin: http://localhost好了一去一回的HTTP请求 如果他们的梦幻字符串都对上了客户端服务端都确定是一次WB请求了。。那就开始建立TCP连接了。关于Tcp编程为什么没有选用Netty或者Mina框架而选用以上的技术。 其实我感觉还是他们太复杂。并且我们用Netty的话集群规则负载均衡JVM优化都需要自己做。集群规则负载均衡这块儿就是另一个大的研究方向一个人根本搞不下来。不如放在容器里。比如Tomcat,你要真嫌弃Tomcat太低端。换Jboss也不是不行他们都做了N年的优化和开发稳定性绝对OK集群规则负载均衡JVM等等都有现成的解决方案还有其他的一些优化 可以说世界顶尖。满足你的高并发一点问题都没。不要重复造轮子别人(JBoss)的集群规则好负载均衡稳定就用就是了所以小的WB应用推荐tomcat,高并发的WB应用推荐Jboss。并且合理设置集群规则合理配置负载均衡合理优化JVM我保证满足你的高并发websocket需求完全不是问题。。加上我们的数据库选型和消息队列都是为高并发添火的技术所以代码写的干净的话高并发完全不是问题。不用纠结WB的效率如何集群怎么做~负载均衡是不是要自己写。。答案是NO。 解决方案是 用高端点的应用容器这就是WB和TCP比的优势他可以在容器里搞~ 集群方案负载均衡方案都是人家做好的。原生的TCP协议你必须自己去解决这些问题。这真是一个大问题想想就知道了单单集群这块儿有几个能做的好的。。先贴pom.xml4.0.0com.mendaowebsocketwar1.0.0门道的即时通讯服务器1.1.393.1.04.0.3.RELEASE3.6.10.Final5.1.301.1.22.0.05.7.02.23.08.0.5com.esotericsoftware.kryokryo${kryo.version}org.apache.activemqactivemq-core${activemq.version}org.apache.xbeanxbean-spring3.17javax.servletjavax.servlet-api${servlet.version}providedjavax.annotationjsr250-api1.0providedjavax.persistencepersistence-api1.0.2providedorg.aspectjaspectjweaver1.7.4xercesxercesImpl2.11.0antlrantlr2.7.7dom4jdom4j1.6.1org.springframeworkspring-aop${spring.version}org.springframeworkspring-context${spring.version}org.springframeworkspring-beans${spring.version}org.springframeworkspring-core${spring.version}org.springframeworkspring-tx${spring.version}org.springframeworkspring-web${spring.version}org.springframeworkspring-webmvc${spring.version}org.springframeworkspring-jdbc${spring.version}org.springframeworkspring-expression${spring.version}org.springframeworkspring-orm${spring.version}org.springframeworkspring-websocket${spring.version}org.springframeworkspring-jms${spring.version}org.springframework.dataspring-data-mongodb1.4.1.RELEASEorg.springframework.dataspring-data-redis1.2.1.RELEASEmysqlmysql-connector-java${mysql.version}com.alibabafastjson${fastjson.version}ch.qos.logbacklogback-classic${logback.version}ch.qos.logbacklogback-core${logback.version}com.googlecode.xmemcachedxmemcached${xmemcached.version}commons-langcommons-lang2.6commons-fileuploadcommons-fileupload1.3commons-codeccommons-codec1.9commons-httpclientcommons-httpclient3.1org.apache.tomcattomcat-websocket${tomcat.version}testorg.apache.tomcattomcat-coyote${tomcat.version}providedROOTorg.apache.maven.pluginsmaven-compiler-plugin2.3.21.71.7UTF-8org.apache.maven.pluginsmaven-resources-plugin2.5UTF-8org.apache.maven.pluginsmaven-war-plugin2.2false然后开始进入正题。web.xml配置。我贴上我的配置。welcome.htmlspringmvcorg.springframework.web.servlet.DispatcherServletcontextClassorg.springframework.web.context.support.AnnotationConfigWebApplicationContextcontextConfigLocationcom.mendao.config.WebConfigspringmvc/org.springframework.web.context.ContextLoaderListenerorg.springframework.web.context.request.RequestContextListenerencodingFilterorg.springframework.web.filter.CharacterEncodingFilterencodingUTF-8forceEncodingtrueencodingFilter/*org.springframework.web.util.IntrospectorCleanupListenerweb.xml没什么可说的了。主要点已经标注。然后贴上com.mendao.config.WebConfig这个类让大家一看究竟完全可以直接复制下来/*** WebSocket 配置类*/Configuration//一定不能少ImportResource(classpath*:/applicationContext.xml) //重要加载spring的其他的xml配置文件这种方式是注解方式xml方式 相结合的配置方式EnableWebSocket //不能少public class WebConfig extends WebMvcConfigurerAdapter implementsWebSocketConfigurer {Resourceprivate BootstrapHandler clientHandler; //注入实例Resourceprivate Bootstrapnterceptor interceptor; //注入实例Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {//重要处理器 URL地址 拦截器 都在这里加入//等会儿帖 处理器和 拦截器的代码//你需要更多处理器 或者URL 都在这里填就是了。其实一般一个就够了一个核心处理器做请求中转。registry.addHandler(clientHandler, /bootstrap).addInterceptors(interceptor);}//Allow serving HTML files through the default Servlet//完全可以无视下面的代码 Overridepublic voidconfigureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable();}}下面是BootstrapHandler 的代码都有注释Servicepublic class BootstrapHandler implementsWebSocketHandler {private final Logger logger LoggerFactory.getLogger(BootstrapHandler.class);ResourceprivateBootstrapHandlerService bootstrapHandlerService;ResourceprivateCached cached;/*** 双工通讯 连接后 并且在这里心跳**paramsession*throwsException*/Overridepublic void afterConnectionEstablished(WebSocketSession session) throwsException {TextMessage textMessage;try{HttpHeaders headerssession.getHandshakeHeaders();String userAgent headers.get(user-agent).get(0);logger.info(LOGIN : userAgent);//构造回应的消息每次连接成功后要回应消息吖告诉客户端已经连接成功了消息就在这里面构造textMessage new TextMessage(“连接成功”);}catch(Exception e) {e.printStackTrace();textMessage new TextMessage(“连接失败”);}//这样就发送给客户端了~ 很简单session.sendMessage(textMessage);}/*** 处理发送过来的消息**paramsession*parammessage*throwsException*/Overridepublic void handleMessage(WebSocketSession session, WebSocketMessage message) throwsException {try{//如果连接成功这里面会不停的接收到心跳包 怎么处理~看你的了 总之这个方法就是接受客户端发来消息的方法// message.getPayload()得到的是客户端发来的消息比如“你好啊” 之类的。得到后转成String就能处理了StringBuffer sb newStringBuffer((String) message.getPayload());//这个是我自己写的一个处理业务逻辑。你可以实现自己的业务逻辑bootstrapHandlerService.handleMessage(session, sb);}catch(Exception e) {e.printStackTrace();logger.error(e.getMessage());}}/*** 客户端 异常断开**paramsession*paramthrowable*throwsException*/Overridepublic void handleTransportError(WebSocketSession session, Throwable throwable) throwsException {logger.info(session.getId() - 异常断开连接);//所谓异常断开例如突然关闭HTML页面等等总之不是用户正常关闭的//这个也是我自己实现的 异常处理的业务逻辑你可以自己写bootstrapHandlerService.handleError(session, throwable);}/*** 连接已经断 开**paramsession*paramstatus*throwsException*/Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throwsException {//只要是断开连接不管是异常断开还是普通正常断开一定会进入这个方法。String reasonstatus.getReason();if (reason null) {reason 客户端 按指令正常退出;}logger.info(session.getId() - 已经主动关闭连接 - 关闭码 - status.getCode() - 缘由 - reason);//其实这里面封装了个session.close()释放了一些资源 也是我自己实现的业务逻辑你也可以自己写bootstrapHandlerService.connectionClose(session);}/*** 握手成功 初始化操作在这里面进行**return*/Overridepublic booleansupportsPartialMessages() {//一旦HTTP认证成功 这个方法先被调用 如果返回true 则进行上面那么N多方法的流程。如果返回的是false就直接拦截掉了。不会调用上面那些方法了//就好像个构造器一样。这个是处理器 BootstrapHandler的构造器~return true;}}然后贴上 Interceptor 拦截器的代码 实现的接口不能变里面没代码的原因是 我实在不知道在这里面做什么操作感觉我的业务是用不到这两个方法。Servicepublic class Bootstrapnterceptor implementsHandshakeInterceptor {/*** 握手前**paramrequest*paramresponse*paramwebSocketHandler*paramstringObjectMap*return*throwsException*/Overridepublic boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler webSocketHandler, Map stringObjectMap) throwsException {return true;}/*** 握手成功后**paramrequest*paramresponse*paramhandler*parame*/Overridepublic voidafterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Exception e) {}}然后我上一个HTML版的客户端测试程序wvarheartbeat_timer 0;varlast_health -1;varhealth_timeout 3000;$(function(){//ws ws_conn( ws://211.100.41.186:9999 );wsws_conn(ws://127.0.0.1:12345/bootstrap);$(#send_btn).click(function(){varmsg$(#mysendbox).val();alert(msg);alert(ws);ws.send(msg);$(#mysendbox).val();});});functionkeepalive( ws ){vartime newDate();if( last_health! -1 ( time.getTime()-last_healthhealth_timeout ) ){//此时即可以认为连接断开可是设置重连或者关闭$(#keeplive_box).html(服务器没有响应.).css({color:red});//ws.close();}else{$(#keeplive_box).html(连接正常).css({color:green});if( ws.bufferedAmount 0){ws.send(1); }}}//websocket functionfunctionws_conn( to_url ){to_urlto_url|| ;if( to_url ){return false;}clearInterval( heartbeat_timer );$(#statustxt).html(Connecting...);varws newWebSocket( to_url );ws.onopenfunction(){$(#statustxt).html(connected.);$(#send_btn).attr(disabled,false);heartbeat_timersetInterval(function(){keepalive(ws)},5000);}ws.οnerrοrfunction(){$(#statustxt).html(error.);$(#send_btn).attr(disabled,true);clearInterval( heartbeat_timer );$(#keeplive_box).html(连接出错.).css({color:red});}ws.onclosefunction(){$(#statustxt).html(closed.);$(#send_btn).attr(disabled,true);clearInterval( heartbeat_timer );$(#keeplive_box).html(连接已关闭.).css({color:red});}ws.onmessagefunction(msg){vartime newDate();if( msg.data(1) ){last_healthtime.getTime();return;}$(#chatbox).val( $(#chatbox).val()msg.data \n);$(#chatbox).attr(scrollTop,$(#chatbox).attr(scrollHeight));}returnws;}web socket连接状态: 连接中...心跳状态检测中...发送文本到Websocket服务器核心的就这么多。这些方法理解了其他的靠自己发挥想象~对了每个不同的连接都会有一个不同的WebSocketSession session 你可以把这个session存入一个全局的ConcurrentHashMap中作为连接池用的时候 用 map.get(key); 然后就能用sendMessage(); 发送给他消息了什么时候存这个session这就看你的业务需要了。总之每个WebSocketSession 标识一个完全不同的新的连接。客户句柄来形容也可以~然后虽然你用上了WB 但是还是要自己做出来。心跳包~ 数据分割处理~ 等等一些基本的业务逻辑~ 什么地方用消息队列分发那就要看你业务怎么设计了。离线消息怎么做可以找我私聊QQ。631768417 有不懂的也可以私聊我QQ最后最有用的websocket可以做移动端 (安卓IOS等)即时通讯服务器。但是需要用到一个jar包。在github上搜索 websocket client (websocket的客户端) 有java的实现也有object-c的实现这个思路提供出来之后你就知道websocket 的强大了吧。不但敏捷开发而且跨平台可以做android推送解决方案 当然也可以整合ios做即时通讯当然HTML更可以因为原生的就是HTML 强大的websocket为企业即时通讯方案提供了更好的出路核心已经讲解更多的发挥想象吧