新闻详细
新闻当前位置:新闻详细

如何设置Weblogic以提高并发处理性能,如何调整WEBLOGIC 11G 线程数

专业编程培训机构——完成蜕变以后轻松拿高薪

电话+V: 152079-09430 ,欢迎咨询weblogic12c增加线程数,[python实用课程],[C++单片机原理],[C#网站搭建],[Nodejs小程序开发],[ios游戏开发],[安卓游戏开发],[教会用大脑用想法赚钱实现阶层跨越]

一、如何设置Weblogic以提高并发处理性能

1.设置Weblogic线程数

将ThreadCount改为一个较大的值,如100。

2.设置WeblogicJDBC缓冲池

3.关闭Weblogic服务器

4.修改startWeblogic.cmd文件

打开{mydomain}\\startWebLogic.cmd,找到下面的行:

@remSetMEM_ARGStothememoryargsyouwanttopasstojava.Forinstance:

@remsetMEM_ARGS=-Xms-Xmx

setMEM_ARGS=

改为:

@remSetMEM_ARGStothememoryargsyouwanttopasstojava.Forinstance:

@remsetMEM_ARGS=-Xms-Xmx

setMEM_ARGS=-Xms-Xmx-XX:MaxPermSize=-XX:MaxNewSize=-XX:NewSize=-XX:ThreadStackSize=

注意第3行是一行,中间没有换行,这里因为显示不下才变成了两行。

二、如何调整WEBLOGIC11G线程数

WEBLOGIC11G线程数的线程数都是自调节的,当然,自己也可以做初始值和最大值的设置,那就需要进行配置文件的修改或者启动参数的修改:

第一方法:直接在启动命令里加上.

-Dweblogic.threadpool.MinPoolSize=800-Dweblogic.threadpool.MaxPoolSize=800

第二方法:直接在配置文件中加上

1,在CONFIG.XML中的

<server>

<name>server_name</name>

<self-tuning-thread-pool-size-min>1000</self-tuning-thread-pool-size-min>

<self-tuning-thread-pool-size-max>1000</self-tuning-thread-pool-size-max>

...

</server>

2、在startweblogic.cmd脚本中加入一下java启动参数:

一文带你入门WebSocket

2019-04-0222:27·java干货分享

WebSocket前世今生

众所周知,Web应用的交互过程通常是客户端通过浏览器发出一个请求,服务器端接收请求后进行处理并返回结果给客户端,客户端浏览器将信息呈现,这种机制对于信息变化不是特别频繁的应用尚可,但对于实时要求高、海量并发的应用来说显得捉襟见肘,尤其在当前业界移动互联网蓬勃发展的趋势下,高并发与用户实时响应是Web应用经常面临的问题,比如金融证券的实时信息,Web导航应用中的地理位置获取,社交网络的实时消息推送等。

传统的请求-响应模式的Web开发在处理此类业务场景时,通常采用实时通讯方案,常见的是:

  • 轮询,原理简单易懂,就是客户端通过一定的时间间隔以频繁请求的方式向服务器发送请求,来保持客户端和服务器端的数据同步。问题很明显,当客户端以固定频率向服务器端发送请求时,服务器端的数据可能并没有更新,带来很多无谓请求,浪费带宽,效率低下。
  • 基于Flash,AdobeFlash通过自己的Socket实现完成数据交换,再利用Flash暴露出相应的接口为JavaScript调用,从而达到实时传输目的。此方式比轮询要高效,且因为Flash安装率高,应用场景比较广泛,但在移动互联网终端上Flash的支持并不好。IOS系统中没有Flash的存在,在Android中虽然有Flash的支持,但实际的使用效果差强人意,且对移动设备的硬件配置要求较高。2012年Adobe官方宣布不再支持Android4.1+系统,宣告了Flash在移动终端上的死亡。
  • 从上文可以看出,传统Web模式在处理高并发及实时性需求的时候,会遇到难以逾越的瓶颈,我们需要一种高效节能的双向通信机制来保证数据的实时传输。在此背景下,基于HTML5规范的、有WebTCP之称的WebSocket应运而生。

    早期HTML5并没有形成业界统一的规范,各个浏览器和应用服务器厂商有着各异的类似实现,如IBM的MQTT,Comet开源框架等,直到2014年,HTML5在IBM、微软、Google等巨头的推动和协作下终于尘埃落地,正式从草案落实为实际标准规范,各个应用服务器及浏览器厂商逐步开始统一,在JavaEE7中也实现了WebSocket协议,从而无论是客户端还是服务端的WebSocket都已完备,读者可以查阅HTML5规范,熟悉新的HTML协议规范及WebSocket支持。

    WebSocket机制

    以下简要介绍一下WebSocket的原理及运行机制。

    WebSocket是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在TCP之上,同HTTP一样通过TCP来传输数据,但是它和HTTP最大不同是:

  • WebSocket是一种双向通信协议,在建立连接后,WebSocket服务器和Browser/ClientAgent都能主动的向对方发送或接收数据,就像Socket一样;
  • WebSocket需要类似TCP的客户端和服务器端通过握手连接,连接成功后才能相互通信。
  • 非WebSocket模式传统HTTP客户端与服务器的交互如下图所示:

    图1.传统HTTP请求响应客户端服务器交互图

    使用WebSocket模式客户端与服务器的交互如下图:

    图2.WebSocket请求响应客户端服务器交互图

    上图对比可以看出,相对于传统HTTP每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket是类似Socket的TCP长连接的通讯模式,一旦WebSocket连接建立后,后续数据都以帧序列的形式传输。在客户端断开WebSocket连接或Server端断掉连接前,不需要客户端和服务端重新发起连接请求。在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。

    我们再通过客户端和服务端交互的报文看一下WebSocket通讯与传统HTTP的不同:

    在客户端,newWebSocket实例化一个新的WebSocket客户端对象,连接类似ws://yourdomain:port/path的服务端WebSocketURL,WebSocket客户端对象会自动解析并识别为WebSocket请求,从而连接服务端端口,执行双方握手过程,客户端发送数据格式类似:

    清单1.WebSocket客户端连接报文

    GET/webfin/websocket/HTTP/1.1

    Host:localhost

    Upgrade:websocket

    Connection:Upgrade

    Sec-WebSocket-Key:xqBt3ImNzJbYqRINxEFlkg==

    Origin:<ahref="http://localhost/"><code>http://localhost</code></a>:8080

    Sec-WebSocket-Version:13

    可以看到,客户端发起的WebSocket连接报文类似传统HTTP报文,”Upgrade:websocket”参数值表明这是WebSocket类型请求,“Sec-WebSocket-Key”是WebSocket客户端发送的一个base64编码的密文,要求服务端必须返回一个对应加密的“Sec-WebSocket-Accept”应答,否则客户端会抛出“ErrorduringWebSockethandshake”错误,并关闭连接。

    服务端收到报文后返回的数据格式类似:

    清单2.WebSocket服务端响应报文

    HTTP/1.1101SwitchingProtocols

    Upgrade:websocket

    Connection:Upgrade

    Sec-WebSocket-Accept:K7DJLdLooIwIG/MOpvWFB3y3FE8=

    “Sec-WebSocket-Accept”的值是服务端采用与客户端一致的密钥计算出来后返回客户端的,“HTTP/1.1101SwitchingProtocols”表示服务端接受WebSocket协议的客户端连接,经过这样的请求-响应处理后,客户端服务端的WebSocket连接握手成功,后续就可以进行TCP通讯了。读者可以查阅WebSocket协议栈了解WebSocket客户端和服务端更详细的交互数据格式。

    在开发方面,WebSocketAPI也十分简单,我们只需要实例化WebSocket,创建连接,然后服务端和客户端就可以相互发送和响应消息,在下文WebSocket实现及案例分析部分,可以看到详细的WebSocketAPI及代码实现。

    WebSocket实现

    如上文所述,WebSocket的实现分为客户端和服务端两部分,客户端(通常为浏览器)发出WebSocket连接请求,服务端响应,实现类似TCP握手的动作,从而在浏览器客户端和WebSocket服务端之间形成一条HTTP长连接快速通道。两者之间后续进行直接的数据互相传送,不再需要发起连接和相应。

    以下简要描述WebSocket服务端API及客户端API。

    WebSocket服务端API

    WebSocket服务端在各个主流应用服务器厂商中已基本获得符合JEEJSR356标准规范API的支持(详见JSR356WebSocketAPI规范),以下列举了部分常见的商用及开源应用服务器对WebSocketServer端的支持情况:

    表1.WebSocket服务端支持

    厂商应用服务器备注IBMWebSphereWebSphere8.0以上版本支持,7.X之前版本结合MQTT支持类似的HTTP长连接甲骨文WebLogicWebLogic12c支持,11g及10g版本通过HTTPPublish支持类似的HTTP长连接微软IISIIS7.0+支持Apache

    TomcatTomcat7.0.5+支持,7.0.2X及7.0.3X通过自定义API支持JettyJetty7.0+支持

    以下我们使用Tomcat7.0.5版本的服务端示例代码说明WebSocket服务端的实现:

    JSR356的WebSocket规范使用javax.websocket.*的API,可以将一个普通Java对象(POJO)使用@ServerEndpoint注释作为WebSocket服务器的端点,代码示例如下:

    清单3.WebSocket服务端API示例

    @ServerEndpoint("/echo")

    publicclassEchoEndpoint{

    @OnOpen

    publicvoidonOpen(Sessionsession)throwsIOException{

    //以下代码省略...

    }

    @OnMessage

    publicStringonMessage(Stringmessage){

    //以下代码省略...

    }

    @Message(maxMessageSize=6)

    publicvoidreceiveMessage(Strings){

    //以下代码省略...

    }

    @OnError

    publicvoidonError(Throwablet){

    //以下代码省略...

    }

    @OnClose

    publicvoidonClose(Sessionsession,CloseReasonreason){

    //以下代码省略...

    }

    }

    代码解释:

    上文的简洁代码即建立了一个WebSocket的服务端,@ServerEndpoint("/echo")的annotation注释端点表示将WebSocket服务端运行在ws://[Server端IP或域名]:[Server端口]/websockets/echo的访问端点,客户端浏览器已经可以对WebSocket客户端API发起HTTP长连接了。

    使用ServerEndpoint注释的类必须有一个公共的无参数构造函数,@onMessage注解的Java方法用于接收传入的WebSocket信息,这个信息可以是文本格式,也可以是二进制格式。

    OnOpen在这个端点一个新的连接建立时被调用。参数提供了连接的另一端的更多细节。Session表明两个WebSocket端点对话连接的另一端,可以理解为类似HTTPSession的概念。

    OnClose在连接被终止时调用。参数closeReason可封装更多细节,如为什么一个WebSocket连接关闭。

    更高级的定制如@Message注释,MaxMessageSize属性可以被用来定义消息字节最大限制,在示例程序中,如果超过6个字节的信息被接收,就报告错误和连接关闭。

    注意:早期不同应用服务器支持的WebSocket方式不尽相同,即使同一厂商,不同版本也有细微差别,如Tomcat服务器7.0.5以上的版本都是标准JSR356规范实现,而7.0.2x/7.0.3X的版本使用自定义API(WebSocketServlet和StreamInbound,前者是一个容器,用来初始化WebSocket环境;后者是用来具体处理WebSocket请求和响应,详见案例分析部分),且Tomcat7.0.3x与7.0.2x的createWebSocketInbound方法的定义不同,增加了一个HttpServletRequest参数,使得可以从request参数中获取更多WebSocket客户端的信息,如下代码所示:

    清单4.Tomcat7.0.3X版本WebSocketAPI

    publicclassEchoServletextendsWebSocketServlet{

    @Override

    protectedStreamInboundcreateWebSocketInbound(StringsubProtocol,

    HttpServletRequestrequest){

    //以下代码省略....

    returnnewMessageInbound(){

    //以下代码省略....

    }

    protectedvoidonBinaryMessage(ByteBufferbuffer)

    throwsIOException{

    //以下代码省略...

    }

    protectedvoidonTextMessage(CharBufferbuffer)throwsIOException{

    getWsOutbound().writeTextMessage(buffer);

    //以下代码省略...

    }

    };

    }

    }

    因此选择WebSocket的Server端重点需要选择其版本,通常情况下,更新的版本对WebSocket的支持是标准JSR规范API,但也要考虑开发易用性及老版本程序移植性等方面的问题,如下文所述的客户案例,就是因为客户要求统一应用服务器版本所以使用的Tomcat7.0.3X版本的WebSocketServlet实现,而不是JSR356的@ServerEndpoint注释端点。

    WebSocket客户端API

    对于WebSocket客户端,主流的浏览器(包括PC和移动终端)现已都支持标准的HTML5的WebSocketAPI,这意味着客户端的WebSocketJavaScirpt脚本具备良好的一致性和跨平台特性,以下列举了常见的浏览器厂商对WebSocket的支持情况:

    表2.WebSocket客户端支持

    浏览器支持情况ChromeChromeversion4+支持FirefoxFirefoxversion5+支持IEIEversion10+支持SafariIOS5+支持AndroidBrowerAndroid4.5+支持

    客户端WebSocketAPI基本上已经在各个主流浏览器厂商中实现了统一,因此使用标准HTML5定义的WebSocket客户端的JavaScriptAPI即可,当然也可以使用业界满足WebSocket标准规范的开源框架,如Socket.io。

    以下以一段代码示例说明WebSocket的客户端实现:

    清单5.WebSocket客户端API示例

    varws=newWebSocket(“ws://echo.websocket.org”);

    ws.onopen=function(){ws.send(“Test!”);};

    ws.onmessage=function(evt){console.log(evt.data);ws.close();};

    ws.onclose=function(evt){console.log(“WebSocketClosed!”);};

    ws.onerror=function(evt){console.log(“WebSocketError!”);};

    第一行代码是在申请一个WebSocket对象,参数是需要连接的服务器端的地址,同HTTP协议开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。

    第二行到第五行为WebSocket对象注册消息的处理函数,WebSocket对象一共支持四个消息onopen,onmessage,onclose和onerror,有了这4个事件,我们就可以很容易很轻松的驾驭WebSocket。

    当Browser和WebSocketServer连接成功后,会触发onopen消息;如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含Server传输过来的数据;当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。我们可以看出所有的操作都是采用异步回调的方式触发,这样不会阻塞UI,可以获得更快的响应时间,更好的用户体验。

    WebSocket案例分析

    以下我们以一个真实的客户案例来分析说明WebSocket的优势及具体开发实现(为保护客户隐私,以下描述省去客户名,具体涉及业务细节的代码在文中不再累述)。

    案例介绍

    该客户为一个移动设备制造商,移动设备装载的是Android/IOS操作系统,设备分两类(以下简称A,B两类),A类设备随时处于移动状态中,B类设备为A类设备的管理控制设备,客户需要随时在B类设备中看到所属A类设备的地理位置信息及状态信息。如A类设备上线,离线的时候,B类设备需要立即获得消息通知,A类设备上报时,B类设备也需要实时获得该上报A类设备的地理位置信息。

    为降低跨平台的难度及实施工作量,客户考虑轻量级的WebApp的方式屏蔽Android/IOS平台的差异性,A类设备数量众多,且在工作状态下A类设备处于不定时的移动状态,而B类设备对A类设备状态变化的感知实时性要求很高(秒级)。

    根据以上需求,A/B类设备信息存放在后台数据库中,A/B类设备的交互涉及Web客户端/服务器频繁和高并发的请求-相应,如果使用传统的HTTP请求-响应模式,B类设备的WebApp上需要对服务进行轮询,势必会对服务器带来大的负载压力,且当A类设备没有上线或者上报等活动事件时,B类设备的轮询严重浪费网络资源。

    解决方案

    综上所述,项目采用WebSocket技术实现实时消息的通知及推送,每当A类设备/B类设备上线登录成功即打开WebSocket的HTTP长连接,新的A类设备上线,位置变化,离线等状态变化通过WebSocket发送实时消息,WebSocketServer端处理A类设备的实时消息,并向所从属的B类设备实时推送。

    WebSocket客户端使用jQueryMobile(jQueryMobile移动端开发在本文中不再详细描述,感兴趣的读者可以参考jQueryMobile简介),使用原生WebSocketAPI实现与服务端交互。

    服务端沿用客户已有的应用服务器Tomcat7.0.33版本,使用Apache自定义API实现WebSocketServer端,为一个上线的A类设备生成一个WebSocket的HTTP长连接,每当A类设备有上线,位置更新,离线等事件的时候,客户端发送文本消息,服务端识别并处理后,向所属B类设备发送实时消息,B类设备客户端接收消息后,识别到A类设备的相应事件,完成对应的A类设备位置刷新以及其他业务操作。

    其涉及的A类设备,B类设备及后台服务器交互时序图如下:

    图3:A/B类设备WebSocket交互图

    A/B类设备的WebSocket客户端封装在websocket.js的JavaScript代码中,与jQueryMobileApp一同打包为移动端apk/ipa安装包;WebSocket服务端实现主要为
    WebSocketDeviceServlet.java,
    WebSocketDeviceInbound.java,
    WebSocketDeviceInboundPool.java几个类。下文我们一一介绍其具体代码实现。

    代码实现

    在下文中我们把本案例中的主要代码实现做解释说明,读者可以下载完整的代码清单做详细了解。

    WebSocketDeviceServlet类

    A类设备或者B类设备发起WebSocket长连接后,服务端接受请求的是WebSocketDeviceServlet类,跟传统HttpServlet不同的是,WebSocketDeviceServlet类实现createWebSocketInbound方法,类似SocketServer的accept方法,新生产的WebSocketInbound实例对应客户端HTTP长连接,处理与客户端交互功能。

    WebSocketDeviceServlet服务端代码示例如下:

    清单
    6.WebSocketDeviceServlet.java代码示例

    publicclassWebSocketDeviceServletextendsorg.apache.catalina.websocket.WebSocketServlet{

    privatestaticfinallongserialVersionUID=1L;

    @Override

    protectedStreamInboundcreateWebSocketInbound(StringsubProtocol,HttpServletRequestrequest){

    WebSocketDeviceInboundnewClientConn=newWebSocketDeviceInbound(request);

    WebSocketDeviceInboundPool.addMessageInbound(newClientConn);

    returnnewClientConn;

    }

    }

    代码解释:

    WebSocketServlet是WebSocket协议的后台监听进程,和传统HTTP请求一样,WebSocketServlet类似Spring/Struct中的Servlet监听进程,只不过通过客户端ws的前缀指定了其监听的协议为WebSocket。


    WebSocketDeviceInboundPool实现了类似JDBC数据库连接池的客户端WebSocket连接池功能,并统一处理WebSocket服务端对单个客户端/多个客户端(同组A类设备)的消息推送,详见
    WebSocketDeviceInboundPool代码类解释。

    WebSocketDeviceInboundl类

    WebSocketDeviceInbound类为每个A类和B类设备验证登录后,客户端建立的HTTP长连接的对应后台服务类,类似Socket编程中的SocketServeraccept后的Socket进程,在WebSocketInbound中接收客户端发送的实时位置信息等消息,并向客户端(B类设备)发送下属A类设备实时位置信息及位置分析结果数据,输入流和输出流都是WebSocket协议定制的。WsOutbound负责输出结果,StreamInbound和WsInputStream负责接收数据:

    清单
    7.WebSocketDeviceInbound.java类代码示例

    publicclassWebSocketDeviceInboundextendsMessageInbound{

    privatefinalHttpServletRequestrequest;

    privateDeviceAccountconnectedDevice;

    publicDeviceAccountgetConnectedDevice(){

    returnconnectedDevice;

    }

    publicvoidsetConnectedDevice(DeviceAccountconnectedDevice){

    this.connectedDevice=connectedDevice;

    }

    publicHttpServletRequestgetRequest(){

    returnrequest;

    }

    publicWebSocketDeviceInbound(HttpServletRequestrequest){

    this.request=request;

    DeviceAccountconnectedDa=(DeviceAccount)request.getSession(true).getAttribute("connectedDevice");

    if(connectedDa==null)

    {

    StringdeviceId=request.getParameter("id");

    DeviceAccountDaodeviceDao=newDeviceAccountDao();

    connectedDa=deviceDao.getDaById(Integer.parseInt(deviceId));

    }

    this.setConnectedDevice(connectedDa);

    }

    @Override

    protectedvoidonOpen(WsOutboundoutbound){

    /

    }

    @Override

    protectedvoidonClose(intstatus){

    WebSocketDeviceInboundPool.removeMessageInbound(this);

    }

    @Override

    protectedvoidonBinaryMessage(ByteBuffermessage)throwsIOException{

    thrownewUnsupportedOperationException("Binarymessagenotsupported.");

    }

    @Override

    protectedvoidonTextMessage(CharBuffermessage)throwsIOException{

    WebSocketDeviceInboundPool.processTextMessage(this,message.toString());

    }

    publicvoidsendMessage(BaseEventevent)

    {

    StringeventStr=JSON.toJSONString(event);

    try{

    this.getWsOutbound().writeTextMessage(CharBuffer.wrap(eventStr));

    //…以下代码省略

    }catch(IOExceptione){

    e.printStackTrace();

    }

    }

    }

    代码解释:

    connectedDevice是当前连接的A/B类客户端设备类实例,在这里做为成员变量以便后续处理交互。

    sendMessage函数向客户端发送数据,使用WebsocketWsOutbound输出流向客户端推送数据,数据格式统一为JSON。

    onTextMessage函数为客户端发送消息到服务器时触发事件,调用
    WebSocketDeviceInboundPool的processTextMessage统一处理A类设备的登入,更新位置,离线等消息。

    onClose函数触发关闭事件,在连接池中移除连接。

    WebSocketDeviceInbound构造函数为客户端建立连接后,WebSocketServlet的createWebSocketInbound函数触发,查询A类/B类设备在后台数据库的详细数据并实例化connectedDevice做为WebSocketDeviceInbound的成员变量,WebSocketServlet类此时将新的WebSocketInbound实例加入自定义的
    WebSocketDeviceInboundPool连接池中,以便统一处理A/B设备组员关系及位置分布信息计算等业务逻辑。


    WebSocketDeviceInboundPool类

    WebSocketInboundPool类:由于需要处理大量A类B类设备的实时消息,服务端会同时存在大量HTTP长连接,为统一管理和有效利用HTTP长连接资源,项目中使用了简单的HashMap实现内存连接池机制,每次设备登入新建的WebSocketInbound都放入WebSocketInbound实例的连接池中,当设备登出时,从连接池中remove对应的WebSocketInbound实例。

    此外,WebSocketInboundPool类还承担WebSocket客户端处理A类和B类设备间消息传递的作用,在客户端发送A类设备登入、登出及位置更新消息的时候,服务端WebSocketInboundPool进行位置分布信息的计算,并将计算完的结果向同时在线的B类设备推送。

    清单
    8.WebSocketDeviceInboundPool.java代码示例

    publicclassWebSocketDeviceInboundPool{

    privatestaticfinalArrayList<WebSocketDeviceInbound>connections=

    newArrayList<WebSocketDeviceInbound>();

    publicstaticvoidaddMessageInbound(WebSocketDeviceInboundinbound){

    //添加连接

    DeviceAccountda=inbound.getConnectedDevice();

    System.out.println("新上线设备:"+da.getDeviceNm());

    connections.add(inbound);

    }

    publicstaticArrayList<DeviceAccount>getOnlineDevices(){

    ArrayList<DeviceAccount>onlineDevices=newArrayList<DeviceAccount>();

    for(WebSocketDeviceInboundwebClient:connections)

    {

    onlineDevices.add(webClient.getConnectedDevice());

    }

    returnonlineDevices;

    }

    publicstaticWebSocketDeviceInboundgetGroupBDevices(Stringgroup){

    WebSocketDeviceInboundretWebClient=null;

    for(WebSocketDeviceInboundwebClient:connections)

    {

    if(webClient.getConnectedDevice().getDeviceGroup().equals(group)

    webClient.getConnectedDevice().getType().equals("B")){

    retWebClient=webClient;

    }

    }

    returnretWebClient;

    }

    publicstaticvoidremoveMessageInbound(WebSocketDeviceInboundinbound){

    //移除连接

    System.out.println("设备离线:"+
    inbound.getConnectedDevice());

    connections.remove(inbound);

    }

    publicstaticvoidprocessTextMessage(WebSocketDeviceInboundinbound,Stringmessage){

    BaseEventreceiveEvent=(BaseEvent)JSON.parseObject(message.toString(),BaseEvent.class);

    DBEventHandleImpldbEventHandle=newDBEventHandleImpl();

    dbEventHandle.setReceiveEvent(receiveEvent);

    dbEventHandle.HandleEvent();

    if(receiveEvent.getEventType()==EventConst.EVENT_MATCHMATIC_RESULT||

    receiveEvent.getEventType()==EventConst.EVENT_GROUP_DEVICES_RESULT||

    receiveEvent.getEventType()==EventConst.EVENT_A_REPAIRE){

    StringclientDeviceGroup=((ArrayList<DeviceAccount>)

    receiveEvent.getEventObjs()).get(0).getDeviceGroup();

    WebSocketDeviceInboundbClient=getGroupBDevices(clientDeviceGroup);

    if(bClient!=null){

    sendMessageToSingleClient(bClient,dbEventHandle.getReceiveEvent());

    }

    }

    }

    }

    publicstaticvoidsendMessageToAllDevices(BaseEventevent){

    try{

    for(WebSocketDeviceInboundwebClient:connections){

    webClient.sendMessage(event);

    }

    }catch(Exceptione){

    e.printStackTrace();

    }

    }

    publicstaticvoidsendMessageToSingleClient(WebSocketDeviceInboundwebClient,BaseEventevent){

    try{

    webClient.sendMessage(event);

    }

    catch(Exceptione){

    e.printStackTrace();

    }

    }

    }

    代码解释:

    addMessageInbound函数向连接池中添加客户端建立好的连接。

    getOnlineDevices函数获取所有的连线的A/B类设备。

    removeMessageInbound函数实现A类设备或者B类设备离线退出(服务端收到客户端关闭WebSocket连接事件,触发WebSocketInbound中的onClose方法),从连接池中删除连接设备客户端的连接实例。

    processTextMessage完成处理客户端消息,这里使用了消息处理的机制,包括解码客户端消息,根据消息构造Event事件,通过EventHandle多线程处理,处理完后向客户端返回,可以向该组B设备推送消息,也可以向发送消息的客户端推送消息。

    sendMessageToAllDevices函数实现发送数据给所有在线A/B类设备客户端。sendMessageToSingleClient函数实现向某一A/B类设备客户端发送数据。

    websocket.js客户端代码

    客户端代码websocket.js,客户端使用标准HTML5定义的WebSocketAPI,从而保证支持IE9+,Chrome,FireFox等多种浏览器,并结合jQueryJS库API处理JSON数据的处理及发送。

    清单9:客户端WebSocket.js脚本示例

    varwebsocket=window.WebSocket||window.MozWebSocket;

    varisConnected=false;

    functiondoOpen(){

    isConnected=true;

    if(deviceType=='B'){

    mapArea='mapB';

    doLoginB(mapArea);

    }

    else{

    mapArea='mapA';

    doLoginA(mapArea);

    }

    }

    functiondoClose(){

    showDiagMsg("infoField","已经断开连接","infoDialog");

    isConnected=false;

    }

    functiondoError(){

    showDiagMsg("infoField","连接异常!","infoDialog");

    isConnected=false;

    }

    functiondoMessage(message){

    varevent=$.parseJSON(message.data);

    doReciveEvent(event);

    }

    functiondoSend(message){

    if(websocket!=null){

    websocket.send(JSON.stringify(message));

    }else{

    showDiagMsg("infoField","您已经掉线,无法与服务器通信!","infoDialog");

    }

    }

    //初始话WebSocket

    functioninitWebSocket(wcUrl){

    if(window.WebSocket){

    websocket=newWebSocket(encodeURI(wcUrl));

    websocket.onopen=doOpen;

    websocket.onerror=doError;

    websocket.onclose=doClose;

    websocket.onmessage=doMessage;

    }

    else{

    showDiagMsg("infoField","您的设备不支持webSocket!","infoDialog");

    }

    };

    functiondoReciveEvent(event){

    //设备不存在,客户端断开连接

    if(event.eventType==101){

    showDiagMsg("infoField","设备不存在或设备号密码错!","infoDialog");

    websocket.close();

    }

    //返回组设备及计算目标位置信息,更新地图

    elseif(event.eventType==104||event.eventType==103){

    clearGMapOverlays(mapB);

    $.each(event.eventObjs,function(idx,item){

    vardeviceNm=item.deviceNm;

    //googleapi

    //vardeviceLocale=newgoogle.maps.LatLng(item.lag,item.lat);

    //baiduapi

    vardeviceLocale=newBMap.Point(item.lng,item.lat);

    varnewMarker;

    if(item.status=='target'){

    newMarker=addMarkToMap(mapB,deviceLocale,deviceNm,true);

    //…以下代码省略

    }

    else{

    newMarker=addMarkToMap(mapB,deviceLocale,deviceNm);

    }

    markArray.push(newMarker);

    });

    showDiagMsg("infoField","有新报修设备或设备离线,地图已更新!","infoDialog");

    }

    }

    代码解释:

    doOpen回调函数处理打开WebSocket,A类设备或者B类设备连接上WebSocket服务端后,将初始化地图并显示默认位置,然后向服务端发送设备登入的消息。

    doReciveEvent函数处理关闭WebSocket,A类/B类设备离线(退出移动终端上的应用)时,服务端关闭HTTP长连接,客户端WebSocket对象执行onclose回调句柄。

    initWebSocket初始化WebSocket,连接WebSocket服务端,并设置处理回调句柄,如果浏览器版本过低而不支持HTML5,提示客户设备不支持WebSocket。

    doSend函数处理客户端向服务端发送消息,注意message是JSONOBJ对象,通过JSON标准API格式化字符串。

    doMessage函数处理WebSocket服务端返回的消息,后台返回的message为JSON字符串,通过jQuery的parseJSONAPI格式化为JSONObject以便客户端处理doReciveEvent函数时客户端收到服务端返回消息的具体处理,由于涉及大量业务逻辑在此不再赘述。

    结束语

    以上简要介绍了WebSocket的由来,原理机制以及服务端/客户端实现,并以实际客户案例指导并讲解了如何使用WebSocket解决实时响应及服务端消息推送方面的问题。本文适用于熟悉HTML协议规范和J2EEWeb编程的读者,旨在帮助读者快速熟悉HTML5WebSocket的原理和开发应用。文中的服务端及客户端项目代码可供下载,修改后可用于用户基于WebSocket的HTTP长连接的实际生产环境中。

    【FUTURE PROGRAMMING COURSE】尊享对接老板

    电话+V: 152079-09430

    机构由一批拥有10年以上开发管理经验,且来自互联网或研究机构的IT精英组成,负责研究、开发教学模式和课程内容。公司具有完善的课程研发体系,一直走在整个行业发展的前端,在行业内竖立起了良好的品质口碑。

    weblogic12c增加线程数
    Copyright2023未知推广科技