基于webSocket的聊天室

时间:2020-12-01 10:08:43

前言

不知大家在平时的需求中有没有遇到需要实时处理信息的情况,如站内信,订阅,聊天之类的。在这之前我们通常想到的方法一般都是采用轮训的方式每隔一定的时间向服务器发送请求从而获得最新的数据,但这样会浪费掉很多的资源并且也不是实时的,于是随着HTML5的推出带来了websocket可以根本的解决以上问题实现真正的实时传输。

websocket是什么?

至于websocket是什么、有什么用这样的问题一Google一大把,这里我就简要的说些websocket再本次实例中的作用吧。
由于在本次实例中需要实现的是一个聊天室,一个实时的聊天室。如下图:
基于webSocket的聊天室

采用websocket之后可以让前端和和后端像C/S模式一样实时通信,不再需要每次单独发送请求。由于是基于H5的所以对于老的浏览器如IE7、IE8之类的就没办法了,不过H5是大势所趋这点不用担心。

后端

既然推出了websocket,作为现在主流的Java肯定也有相应的支持,所以在JavaEE7之后也对websocket做出了规范,所以本次的代码理论上是要运行在Java1.7+和Tomcat7.0+之上的。
看过我前面几篇文章的朋友应该都知道本次实例也是运行在之前的SSM之上的,所以这里就不再赘述了。
首先第一步需要加入websocket的依赖:

  1 package com.css.tax.mobilebs.util;
  2 
  3 import java.io.IOException;
  4 import java.io.UnsupportedEncodingException;
  5 import java.util.Date;
  6 import java.util.HashMap;
  7 import java.util.Iterator;
  8 import java.util.Map;
  9 import java.util.concurrent.CopyOnWriteArraySet;
 10 
 11 import javax.websocket.OnClose;
 12 import javax.websocket.OnError;
 13 import javax.websocket.OnMessage;
 14 import javax.websocket.OnOpen;
 15 import javax.websocket.Session;
 16 import javax.websocket.server.PathParam;
 17 import javax.websocket.server.ServerEndpoint;
 18 
 19 import org.g4studio.common.dao.Reader;
 20 import org.g4studio.common.service.impl.BaseServiceImpl;
 21 import org.g4studio.common.util.SpringBeanLoader;
 22 import org.g4studio.common.web.BaseAction;
 23 import org.g4studio.core.metatype.Dto;
 24 import org.g4studio.core.metatype.impl.BaseDto;
 25 import org.junit.Test;
 26 
 27 import com.css.tax.mobilebs.Vo.CurrentUserVo;
 28 import com.css.tax.mobilebs.serviceI.WebSocketService;
 29 import com.css.tax.mobilebs.serviceI.ZjzzService;
 30 
 31 /**
 32 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
 33 * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 34 */
 35 @ServerEndpoint("/websocket/{user}/{id}/{ptbz}")
 36 public class WebSocket extends BaseAction{
 37 // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
 38 private static int onlineCount = 0;
 39 // concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
 40 private static CopyOnWriteArraySet<Map<String, WebSocket>> webSocketSet = new CopyOnWriteArraySet<Map<String, WebSocket>>();
 41 private static CopyOnWriteArraySet<Map<String, WebSocket>> webSocketSetPt = new CopyOnWriteArraySet<Map<String, WebSocket>>();
 42 private WebSocketService zjzzWebSocketService = (WebSocketService)super.getService("zjzzWebSocketService");
 43 // 与某个客户端的连接会话,需要通过它来给客户端发送数据
 44 private Session session;
 45 private Map<String, WebSocket> webSocketMap = new HashMap<String, WebSocket>();
 46 private CurrentUserVo currentUserVo = new CurrentUserVo();
 47 
 48 /**
 49 * 连接建立成功调用的方法
 50 * 
 51 * @param session
 52 * 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
 53 */
 54 @OnOpen
 55 public void onOpen(@PathParam("user") String user,
 56 @PathParam("id") String id, @PathParam("ptbz") String ptbz,
 57 Session session) {
 58 String charset = getEncoding(user);
 59 try {
 60 byte[] b = user.getBytes(charset);
 61 user = new String(b, "utf-8");
 62 } catch (UnsupportedEncodingException e) {
 63 e.printStackTrace();
 64 }
 65 this.session = session;
 66 currentUserVo.setFbrmc(user);
 67 currentUserVo.setFbr(id);
 68 currentUserVo.setPtbz(ptbz);
 69 currentUserVo.setTwr_dm(id);
 70 currentUserVo.setPtbz(ptbz);
 71 webSocketMap.put(id, this);
 72 if("pt".equals(ptbz)) {
 73 currentUserVo.setZjmc(user);
 74 currentUserVo.setZjry_dm(id);
 75 currentUserVo.setKhdfwr(id);
 76 webSocketSetPt.add(webSocketMap);
 77 }else{
 78 currentUserVo.setNsrmc(user);
 79 webSocketSet.add(webSocketMap); // 加入set中
 80 }
 81 addOnlineCount(); // 在线数加
 82 System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
 83 }
 84 
 85 /**
 86 * 连接关闭调用的方法
 87 */
 88 @OnClose
 89 public void onClose() {
 90 if("pt".equals(this.currentUserVo.getPtbz())) {
 91 webSocketSetPt.remove(this.webSocketMap);
 92 }else{
 93 webSocketSet.remove(this.webSocketMap); // 从set中删除
 94 }
 95 subOnlineCount(); // 在线数减
 96 System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
 97 }
 98 
 99 /**
100 * 收到客户端消息后调用的方法
101 * 
102 * @param message
103 * 客户端发送过来的消息
104 * @param session
105 * 可选的参数
106 */
107 @OnMessage
108 public void onMessage(String message,Session session) {
109 boolean boo = false;
110 
111 System.out.println("来自" + currentUserVo.getFbrmc() + "的消息:" + message+",发向"+currentUserVo.getJsr_dm());
112 //判断是否为未读消息
113 int a = message.indexOf("&&&");
114 System.out.println(a);
115 if(a!=-1) {//为未读消息
116 String[] msgStr = message.split("&&&");
117 String userMes = msgStr[0];
118 String[] user = userMes.split("@");
119 String uuid = "";
120 String wdjsr = "";
121 String fbrmc = "";
122 String fbr = "";
123 String zjzzuuid = "";
124 if(user.length>0) {
125 wdjsr = user[0];
126 uuid = user[1];
127 fbrmc = user[2];
128 fbr = user[3];
129 zjzzuuid = user[4];
130 }
131 message = msgStr[1];
132 CopyOnWriteArraySet<Map<String, WebSocket>> websocketSet = null;
133 if("pt".equals(this.currentUserVo.getPtbz())) {
134 websocketSet = webSocketSetPt;
135 }else{
136 websocketSet = webSocketSet;
137 }
138 if(!"everybody".equals(wdjsr)) {
139 //消息有指定平台用户
140 for (Map<String, WebSocket> itemMap : websocketSet) {
141 WebSocket socket = itemMap.get(wdjsr);
142 if(socket!=null) {
143 try {
144 if("pt".equals(this.currentUserVo.getPtbz())) {
145 socket.sendMessage(fbr+"@@"+fbrmc + "@^&" + message);
146 socket.currentUserVo.setKhdfwr(this.currentUserVo.getFbr());
147 }else{
148 socket.sendMessage(fbrmc + "@^&" + message);
149 socket.currentUserVo.setKhdfwr(fbr);
150 }
151 socket.currentUserVo.setJsr_dm(fbr);//设置该对话的接收人代码
152 socket.currentUserVo.setJsr(fbrmc);
153 socket.currentUserVo.setZjzzuuid(zjzzuuid);
154 boo = true;
155 Dto reDto = new BaseDto();
156 reDto.put("uuid", uuid);
157 reDto.put("ckbz", "Y");
158 reDto.put("xgr_dm", "111");
159 reDto.put("xgsj", SystemUtils.dateFormat(new Date()));
160 zjzzWebSocketService.updateLtxxDatas(reDto);
161 } catch (IOException e) {
162 e.printStackTrace();
163 }
164 }
165 }
166 }else{
167 //未读消息没有指定平台用户
168 if("pt".equals(this.currentUserVo.getPtbz())) {
169 Object[] objArr = webSocketSetPt.toArray();
170 int index = (int) (Math.random() * objArr.length);
171 Map<String, WebSocket> map = (Map<String, WebSocket>) objArr[index];
172 for (WebSocket socket : map.values()) { 
173 if(socket!=null) {
174 try {
175 boo = true;
176 socket.sendMessage(fbr+"@@"+fbrmc + "@^&" + message);
177 socket.currentUserVo.setZjzzuuid(zjzzuuid);
178 socket.currentUserVo.setJsr_dm(fbr);
179 socket.currentUserVo.setJsr(fbrmc);
180 socket.currentUserVo.setKhdfwr(socket.currentUserVo.getFbr());
181 //修改未读对话记录
182 Dto reDto = new BaseDto();
183 reDto.put("uuid", uuid);
184 reDto.put("jsr", this.currentUserVo.getFbr());
185 reDto.put("ckbz", "Y");
186 reDto.put("khdfwr", this.currentUserVo.getKhdfwr());
187 reDto.put("xgr_dm", "111");
188 reDto.put("xgsj", SystemUtils.dateFormat(new Date()));
189 zjzzWebSocketService.updateWdWzdDatas(reDto);
190 } catch (IOException e) {
191 e.printStackTrace();
192 continue;
193 }
194 }
195 }
196 }
197 }
198 }else{
199 String[] xxArr = message.split("@@");
200 String bz = "";
201 String zjzzuuid = "";
202 String fsmessage = "";
203 String jsr = "";
204 if(!"pt".equals(this.currentUserVo.getPtbz())) {
205 String userXx = xxArr[0];
206 String[] user = userXx.split("&&");
207 bz = user[0];
208 zjzzuuid = user[1];
209 this.currentUserVo.setZjzzuuid(zjzzuuid);
210 fsmessage = xxArr[1];
211 }else{
212 String[] xx = message.split("&@");
213 jsr = xx[0];
214 fsmessage = xx[1];
215 }
216 if("pt".equals(this.currentUserVo.getPtbz())) {
217 if(jsr!=null&&jsr.length()>0) {
218 //平台发送消息,发向指定客户端
219 boolean pdboo = false;
220 for (Map<String, WebSocket> itemMap : webSocketSet) {
221 WebSocket socket = itemMap.get(jsr);
222 if(socket!=null) {
223 try {
224 boo = true;
225 pdboo = true;
226 socket.sendMessage(currentUserVo.getFbrmc() + "@^&" + fsmessage);
227 //this.currentUserVo.setJsr_dm(socket.currentUserVo.getFbr());
228 //this.currentUserVo.setJsr(socket.currentUserVo.getFbrmc());
229 //存储已查看对话信息
230 if(socket.currentUserVo.getZjzzuuid()==null) {
231 socket.currentUserVo.setZjzzuuid(this.currentUserVo.getZjzzuuid());
232 }
233 saveYckMessage(socket.currentUserVo.getZjzzuuid(),"Y",fsmessage,"Y",jsr);
234 } catch (IOException e) {
235 e.printStackTrace();
236 continue;
237 }
238 }
239 }
240 if(!pdboo) {
241 this.currentUserVo.setJsr_dm(jsr);
242 String uuid = zjzzWebSocketService.queryZjzzuuidByJsr(jsr);
243 this.currentUserVo.setZjzzuuid(uuid);
244 boo = true;
245 saveYckMessage(uuid,"Y",fsmessage,"N",this.currentUserVo.getJsr_dm());
246 }
247 }
248 }else{
249 if(this.currentUserVo.getJsr_dm()!=null&&this.currentUserVo.getJsr_dm().length()>0) {
250 //该客户端消息已有接收对象,顺利发送给平台
251 for (Map<String, WebSocket> itemMap : webSocketSetPt) {
252 WebSocket socket = itemMap.get(currentUserVo.getJsr_dm());
253 if(socket!=null) {
254 try {
255 boo = true;
256 socket.sendMessage(currentUserVo.getFbr()+"@@"+currentUserVo.getFbrmc() + "@^&" + fsmessage);
257 //存储已查看对话信息
258 saveYckMessage(zjzzuuid,bz,fsmessage,"Y",this.currentUserVo.getJsr_dm());
259 } catch (IOException e) {
260 e.printStackTrace();
261 continue;
262 }
263 }
264 }
265 }else{
266 //该客户端尚未有接收对象,需要随机指定接收对象,并连接发送消息
267 if(webSocketSetPt.size()>0){
268 //平台有用户连接
269 Object[] objArr = webSocketSetPt.toArray();
270 int index = (int) (Math.random() * objArr.length);
271 Map<String, WebSocket> map = (Map<String, WebSocket>) objArr[index];
272 for (WebSocket socket : map.values()) { 
273 if(socket!=null) {
274 try {
275 boo = true;
276 socket.sendMessage(currentUserVo.getFbr()+"@@"+currentUserVo.getFbrmc() + "@^&" + fsmessage);
277 socket.currentUserVo.setJsr_dm(this.currentUserVo.getFbr());
278 socket.currentUserVo.setJsr(this.currentUserVo.getFbrmc());
279 this.currentUserVo.setKhdfwr(socket.currentUserVo.getFbr());
280 this.currentUserVo.setJsr_dm(socket.currentUserVo.getFbr());
281 this.currentUserVo.setZjry_dm(socket.currentUserVo.getFbr());
282 this.currentUserVo.setZjmc(socket.currentUserVo.getFbrmc());
283 this.currentUserVo.setJsr(socket.currentUserVo.getFbrmc());
284 //存储已查看对话信息
285 saveYckMessage(zjzzuuid,bz,fsmessage,"Y",this.currentUserVo.getJsr_dm());
286 } catch (IOException e) {
287 e.printStackTrace();
288 continue;
289 }
290 }
291 }
292 }else{
293 try {
294 this.sendMessage("系统:消息已发送,但当前未有服务人员链接,无法为您解答疑问!");
295 //平台没有用户连接,无法发送消息,保存数据为所有人可接收的未读消息
296 this.currentUserVo.setJsr_dm("everybody");
297 this.currentUserVo.setZjry_dm("everybody");
298 this.currentUserVo.setKhdfwr("everybody");
299 saveYckMessage(zjzzuuid,bz,fsmessage,"N",this.currentUserVo.getJsr_dm());
300 boo = true;
301 } catch (IOException e) {
302 e.printStackTrace();
303 }
304 }
305 }
306 }
307 
308 }
309 if(!boo){
310 if(this.currentUserVo.getJsr_dm()!=null&&this.currentUserVo.getZjzzuuid()!=null) {
311 if("pt".equals(this.currentUserVo.getPtbz())) {
312 saveYckMessage(this.currentUserVo.getZjzzuuid(),"Y",message,"N",this.currentUserVo.getJsr_dm());
313 }else{
314 //存储未查看对话信息
315 String[] xxArr = message.split("@@");
316 String userXx = xxArr[0];
317 String[] user = userXx.split("&&");
318 String bz = user[0];
319 String zjzzuuid = user[1];
320 String fsmessage = xxArr[1];
321 saveYckMessage(zjzzuuid,bz,fsmessage,"N",this.currentUserVo.getJsr_dm());
322 }
323 }else{
324 try {
325 this.sendMessage("系统:消息未发出,可能是连接失败!请重新连接");
326 } catch (IOException e) {
327 e.printStackTrace();
328 }
329 }
330 }
331 }
332 
333 /**
334 * 
335 * @param zjzzuuid    对话组uuid
336 * @param bz    是否存在对话组标志
337 * @param message    对话信息
338 * @param ckbz    对话是否查看标志
339 */
340 private void saveYckMessage(String zjzzuuid,String bz,String message,String ckbz,String jsr) {
341 Dto dto = new BaseDto();
342 String fbrmc = currentUserVo.getFbrmc();
343 String fbr = currentUserVo.getFbr();
344 String khdfwr = currentUserVo.getKhdfwr();
345 if("N".equals(bz)) {//是否有uuid,判断其在数据库中是否存在已有信息
346 //数据库没有该对话记录,故需创建对话记录
347 dto.put("uuid", zjzzuuid);
348 //以下需前台传值
349 dto.put("twr_dm", currentUserVo.getTwr_dm());
350 dto.put("nsrsbh", currentUserVo.getNsrsbh());
351 dto.put("nsrmc", currentUserVo.getNsrmc());
352 dto.put("zjmc", currentUserVo.getZjmc());
353 dto.put("zjry_dm", currentUserVo.getZjry_dm());
354 dto.put("fbr", fbr);
355 dto.put("fbrmc", fbrmc);
356 dto.put("jsr", jsr);
357 dto.put("lrr_dm", fbr);
358 dto.put("lrrq", SystemUtils.dateFormat(new Date()));
359 zjzzWebSocketService.insertZjzzDhjl(dto);
360 
361 Dto dto1 = new BaseDto();
362 dto1.put("lrr_dm", fbr);
363 dto1.put("lrrq", SystemUtils.dateFormat(new Date()));
364 dto1.put("uuid", SystemUtils.genUUID());
365 dto1.put("zjzzuuid", zjzzuuid);
366 dto1.put("dhnr", message);
367 dto1.put("dhsj", SystemUtils.dateFormat(new Date()));
368 dto1.put("fbr", fbr);
369 dto1.put("ckbz", ckbz);
370 dto1.put("khdfwr", khdfwr);
371 dto1.put("fbrmc", fbrmc);
372 dto1.put("jsr", jsr);
373 zjzzWebSocketService.insertZjzzMxDhjlByUuid(dto1);
374 }else{
375 Dto redto = new BaseDto();
376 redto.put("lrr_dm", fbr);
377 redto.put("lrrq", SystemUtils.dateFormat(new Date()));
378 redto.put("uuid", SystemUtils.genUUID());
379 redto.put("zjzzuuid", zjzzuuid);
380 redto.put("dhnr", message);
381 redto.put("dhsj", SystemUtils.dateFormat(new Date()));
382 redto.put("fbr", fbr);
383 redto.put("ckbz", ckbz);
384 redto.put("khdfwr", khdfwr);
385 redto.put("fbrmc", fbrmc);
386 redto.put("jsr", jsr);
387 zjzzWebSocketService.insertZjzzMxDhjlByUuid(redto);
388 }
389 }
390 
391 /**
392 * 发生错误时调用
393 * 
394 * @param session
395 * @param error
396 */
397 @OnError
398 public void onError(Session session, Throwable error) {
399 System.out.println("发生错误");
400 error.printStackTrace();
401 }
402 
403 /**
404 * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
405 * 
406 * @param message
407 * @throws IOException
408 */
409 public void sendMessage(String message) throws IOException {
410 this.session.getBasicRemote().sendText(message);
411 // this.session.getAsyncRemote().sendText(message);
412 }
413 
414 public static synchronized int getOnlineCount() {
415 return onlineCount;
416 }
417 
418 public static synchronized void addOnlineCount() {
419 WebSocket.onlineCount++;
420 }
421 
422 public static synchronized void subOnlineCount() {
423 WebSocket.onlineCount--;
424 }
425 
426 public static String getEncoding(String str) {
427 String encode = "GB2312";
428 try {
429 if (str.equals(new String(str.getBytes(encode), encode))) { // 判断是不是GB2312
430 String s = encode;
431 return s; // 是的话,返回GB2312,以下代码同理
432 }
433 } catch (Exception e) {
434 e.printStackTrace();
435 }
436 encode = "ISO-8859-1";
437 try {
438 if (str.equals(new String(str.getBytes(encode), encode))) { // 判断是不是ISO-8859-1
439 String s1 = encode;
440 return s1;
441 }
442 } catch (Exception e) {
443 e.printStackTrace();
444 }
445 encode = "UTF-8";
446 try {
447 if (str.equals(new String(str.getBytes(encode), encode))) { // 判断是不是UTF-8编码
448 String s2 = encode;
449 return s2;
450 }
451 } catch (Exception e) {
452 e.printStackTrace();
453 }
454 encode = "GBK";
455 try {
456 if (str.equals(new String(str.getBytes(encode), encode))) { // 判断是不是GBK
457 String s3 = encode;
458 return s3;
459 }
460 } catch (Exception e) {
461 e.printStackTrace();
462 }
463 return ""; // 到这一步,你就应该检查是不是其他编码啦
464 }
465 }

这就是整个websocket的后端代码。看起来也比较简单主要就是使用那几个注解。每当有一个客户端连入、关闭、发送消息都会调用各自注解的方法。这里我讲一下sendMessage()这个方法。

websocket绕坑

sendMessage()方法中我只想实现一个简单的功能,就是将每次的聊天记录都存到数据库中。看似一个简单的功能硬是花了我半天的时间。
我先是按照以前的惯性思维只需要在这个类中注入service即可。但是无论怎么弄每次都注入不进来都是null
最后没办法只有google了,最后终于在神级社区*中找到了答案,就是前边所说的需要添加的第二个 maven依赖,然后加入@ServerEndpoint(value = "/websocket",configurator = SpringConfigurator.class)这个注解即可利用Spring注入了。接着就可以做消息的保存了。

前端

前端我采用了Ext.js做的。还是先贴一下代码:

zxws_main.html
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="UTF-8">
 5 <title>Parent Page</title>
 6 <link rel="stylesheet" type="text/css" href="css/Globle.css" />
 7 <link rel="stylesheet" type="text/css" href="css/index.css" />
 8 <script src="js/jquery-1.12.0.min.js" type="text/javascript"
 9     charset="utf-8"></script>
10 <style type="text/css">
11 #main_left div {
12     background: #D1D1D1;
13     border-bottom: 1px #DDDDDD solid;
14 }
15 
16 #main_left input {
17     font-size: 14px;
18     text-align: center;
19     height: 40px;
20     width: 150px;
21     line-height: 40px;
22     color: white;
23 }
24 
25 #main_left span {
26     background: red none repeat scroll 0 0;
27     border-radius: 9px;
28     display: inline-block;
29     height: 18px;
30     line-height: 18px;
31     width: 18px;
32     text-align: center;
33     color: white;
34     display: none;
35 
36 }
37 
38 #add {
39     position: absolute;
40     bottom: 200px;
41 }
42 .butt{
43     height:30px;
44     width: 40px;
45     margin-top: 80px;
46     margin-left: -391px;
47     display: inline-block;
48 }
49 </style>
50 </head>
51 <body>
52     <button class="butt" type="button" class="fs" onclick="()">清理</button>
53     <div id="main">
54         <div id="main_left">
55             <!--<h1>This is the Parent Page.</h1>-->
56 
57         </div>
58         <div id="main_right">
59             <iframe style="width: 600px; height: 540px;" id="childframe"
60                 name="childframe" src="zxws.jsp"></iframe>
61         </div>
62     </div>
63     <script type="text/javascript" src="js/map.js"></script>
64 
65 </body>
66 <script type="text/javascript" src="zxws_main.js"></script>
67 </html>
zxws_main.js
  1 /**
  2  * Created by wanglei on 2017-07-03.
  3  */
  4 var user = GetQueryString("user");
  5 var id = GetQueryString("id");
  6 var ptbz = GetQueryString("ptbz");//客户端为:khd;平台为:pt;
  7 var uuid = "";
  8 var websocket = null;
  9 var jsonStr = localStorage.getItem('WSBS_PT_ZXBS_'+id);
 10 var jsonObj2;
 11 var userOnLineMap = new Map();
 12 function GetQueryString(name) {
 13     var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
 14     var r = decodeURI(window.location.search).substr(1).match(reg);
 15     if (r != null)
 16         return unescape(r[2]);
 17     return null;
 18 }
 19 var zxwin = window;
 20 var parentWin;
 21 // 定义最后光标对象
 22 
 23 var lastEditRange, selection;
 24 //判断当前浏览器是否支持WebSocket
 25 if ('WebSocket' in window) {
 26     websocket = new WebSocket("ws://222.90.69.254:7001/mobile/websocket/"
 27             + user+"/"+id+"/"+ptbz);
 28 } else {
 29     alert('当前浏览器 Not support websocket,请更换浏览器');
 30 }
 31 //连接发生错误的回调方法
 32 websocket.onerror = function() {
 33     setMessageInnerHTML("WebSocket连接发生错误");
 34 };
 35 //连接成功建立的回调方法
 36 websocket.onopen = function(aa) {
 37     //setMessageInnerHTML("WebSocket连接成功");
 38     //查看是否有未读消息,并发送消息
 39     if(jsonStr==null||jsonStr.length==0||jsonStr=="{}") {
 40         jsonObj2 = {};
 41         var o = document.getElementById("main_right");
 42         o.style.visibility="hidden";
 43     }else{
 44         jsonObj2 = JSON.parse(jsonStr);
 45         //document.getElementById("main_right").innerHTML = "<iframe style='width:600px; height:540px;' id='childframe' name='childframe' src='zxws.jsp'></iframe>";
 46     }
 47     $.ajax({  
 48         method:"POST",  
 49         data:{
 50             "twr_dm":id,
 51             "ptbz":ptbz
 52         },
 53         url:"../zjzz.do?reqCode=initDhxx",  
 54         success: function(msg){ 
 55             var datareq = eval('(' + msg + ')');
 56             if(msg!=null&&msg!='[]'){  
 57                 //debugger;
 58                 if("pt"!=ptbz) {
 59                     uuid = datareq.uuid;
 60                     document.getElementById("uuid").setAttribute("uuid", datareq.uuid);
 61                     bz = datareq.bz;
 62                     document.getElementById("uuid").setAttribute("bz", datareq.bz);
 63                 }
 64                 $.ajax({  
 65                     method:"POST",  
 66                     data : {
 67                         //"zjzzuuid" : document.getElementById("uuid").getAttribute("uuid"),
 68                         "jsr" : id
 69                     },
 70                     url:"../zjzz.do?reqCode=queryLtxxDatas",  
 71                     success: function(msg){ 
 72                         //debugger;                                        
 73                         //初始化历史聊天记录
 74                         var json = eval(jsonObj2);
 75                         //localStorage.removeItem('WSBS_PT_ZXBS_'+id);
 76                         var a = 1;
 77                         if(jsonStr!=null&&jsonStr.length>0) {
 78                             for (var prop in json)  
 79                             {   
 80                                 var userArray = prop.split("@");
 81                                 var jsrid = userArray[0];
 82                                 var jsrmc = userArray[1];
 83                                 //alert(jsrid+"~~"+jsrmc);
 84                                 if(jsrmc!=undefined&&jsrmc!=null&&jsrmc.length>0) {
 85                                     userOnLineMap.put(jsrid, jsrmc);
 86                                     $("#main_left").append("<div><input id='"+jsrid+"'/><span id='"+jsrid+"_span'></span></div>");
 87                                     $("#"+jsrid).attr("value",jsrmc);
 88                                     $("#"+jsrid).attr("type","button");
 89                                     $("#"+jsrid).attr("onclick","btnClick('"+jsrid+"')");
 90                                     if(a==1) {
 91                                         var jsrMsg = jsonObj2[prop];
 92                                         var obj = window.frames["childframe"].document;
 93                                         //debugger;
 94                                         window.frames["childframe"].document.getElementById("uuid").setAttribute("bz", "Y");
 95                                         window.frames["childframe"].document.getElementById("uuid").setAttribute("fsrid",jsrid);
 96                                         window.frames["childframe"].document.getElementById("uuid").setAttribute("fsrmc",jsrmc);
 97                                         for (var i = 0; i < jsrMsg.length; i++) {
 98                                             var fsr = jsrMsg[i].fsr;
 99                                             if(fsr==jsrid) {
100                                                 var c1 = obj.getElementById("dhk");
101                                                 var div1 = obj.createElement("div");
102                                                 div1.className = "org_div";
103                                                 
104                                                 /*var now = new Date(); 
105                                                 var nowTime = now.toLocaleString(); 
106                                                 var date = nowTime.substring(0,10);//截取日期 
107                                                 var time = nowTime.substring(10,20);*/
108                                                 
109                                                 var yhDiv = obj.createElement("span");
110                                                 yhDiv.className = "org_yh1";
111                                                 yhDiv.innerHTML = jsrMsg[i].fsrmc+":";
112                                                 var newDiv = obj.createElement("p");
113                                                 newDiv.className = "org_box";
114                                                 newDiv.innerHTML = jsrMsg[i].dhnr;
115                                                 var sjDiv = document.createElement("p");
116                                                 sjDiv.className = "org_sj2";
117                                                 sjDiv.innerHTML = jsrMsg[i].lrrq;
118                                                 //var lrrq = time;
119                                                 //sjDiv.innerHTML = lrrq;
120                                                 div1.appendChild(yhDiv);
121                                                 div1.appendChild(newDiv);
122                                                 div1.appendChild(sjDiv);
123                                                 c1.appendChild(div1);
124                                             }else{
125                                                 var c1 = obj.getElementById("dhk");
126                                                 var div1 = obj.createElement("div");
127                                                 div1.className = "org_div";
128                                                 
129                                                 /*var now = new Date(); 
130                                                 var nowTime = now.toLocaleString(); 
131                                                 var date = nowTime.substring(0,10);//截取日期 
132                                                 var time = nowTime.substring(10,20);*/
133                                                 
134                                                 var yhDiv = obj.createElement("span");
135                                                 yhDiv.className = "org_yh";
136                                                 yhDiv.innerHTML = ":我";
137                                                 var newDiv = obj.createElement("p");
138                                                 newDiv.className = "org_hf";
139                                                 newDiv.innerHTML = jsrMsg[i].dhnr;
140                                                 var sjDiv = document.createElement("p");
141                                                 sjDiv.className = "org_sj1";                                         
142                                                 //var lrrq = time;
143                                                 //sjDiv.innerHTML = lrrq;
144                                                 sjDiv.innerHTML = jsrMsg[i].lrrq;
145                                                 div1.appendChild(yhDiv);
146                                                 div1.appendChild(newDiv);
147                                                 div1.appendChild(sjDiv);
148                                                 c1.appendChild(div1);
149                                                 c1.scrollTop = c1.scrollHeight;
150                                             }
151                                         }
152                                     }
153                                     a = a+1;
154                                 }
155                             }  
156                         }
157                         if(msg!=null){  
158                             var datareq = eval('(' + msg + ')');
159                             for ( var int = 0; int < datareq.length; int++) {
160                                 var msg = datareq[int].dhnr;
161                                 var dhuuid = datareq[int].uuid;
162                                 var wdjsr = datareq[int].jsr;
163                                 var fbrmc = datareq[int].fbrmc;
164                                 var fbr = datareq[int].fbr;
165                                 var zjzzuuid = '';
166                                 if("pt"!=ptbz) {
167                                     zjzzuuid = document.getElementById("uuid").getAttribute("uuid");
168                                 }else{
169                                     zjzzuuid = datareq[int].zjzzuuid;
170                                 }
171                                 websocket.send(wdjsr+"@"+dhuuid+"@"+fbrmc+"@"+fbr+"@"+zjzzuuid+"&&&"+msg);
172                             }
173                         }  
174                     }  
175                  });
176             }  
177         }  
178     });
179 }
180 //接收到消息的回调方法
181 websocket.onmessage = function(event) {
182     debugger;
183     var o = document.getElementById("main_right");
184     if(o.style.visibility=="hidden") {
185         o.style.visibility="visible";
186         //document.getElementById("main_right").innerHTML = "<iframe style='width:600px; height:540px;' id='childframe' name='childframe' src='zxws.jsp'></iframe>";
187     }
188     var mes = event.data;
189     var msg = "";
190     var jsr = "";
191     if(ptbz=='pt') {
192         var arr = mes.split('@@');
193         jsr = arr[0];//设置当前tab的id,即接收人
194         msg = arr[1];
195     }else{
196         msg= mes;
197     }
198     var fsrArr = msg.split('@^&');
199     var fsr = fsrArr[0];
200     msg = fsrArr[1];
201     var xxUser = userOnLineMap.get(jsr);
202     debugger;
203     if(xxUser!=undefined && xxUser.length>0) {
204         
205     }else{
206         userOnLineMap.put(jsr, fsr);
207         $("#main_left").append("<div><input id='"+jsr+"'/><span id='"+jsr+"_span'></span></div>");
208         $("#"+jsr).attr("value",fsr);
209         $("#"+jsr).attr("type","button");
210         $("#"+jsr).attr("onclick","btnClick('"+jsr+"')");
211     }
212     if (fsr != user) {
213         var obj = window.frames["childframe"].document.getElementById("uuid");
214         if(obj.getAttribute("fsrid")!=undefined&&obj.getAttribute("fsrid")!=jsr) {
215             var num = document.getElementById(jsr+"_span").innerHTML;
216             if(num==null) {
217                 num=0;
218             }
219             var num1 = num-0+1;
220             document.getElementById(jsr+"_span").innerHTML=num1;
221             if(num1>0){
222                 document.getElementById(jsr+"_span").style.display='inline-block';
223             }
224             //如果是新用户进来得先走这步,所以再这里就要给它加上日期,如果是老用户的话直接跳到else里去执行了,走到发送里面在给加日期
225             var now = new Date(); 
226             var lrrq = now.toLocaleString(); 
227             var date = lrrq.substring(0,10);//截取日期 
228             var time = lrrq.substring(10,20);
229             
230             var dataJson = {'fsr':jsr,'jsr':id,'fsrmc':fsr,'dhnr':msg,'lrrq':lrrq};
231             document.getElementById("childframe").contentWindow.updateLocalStorage(jsr,fsr,dataJson);
232         }else{
233             obj.setAttribute("fsrid",jsr);
234             obj.setAttribute("fsrmc",fsr);
235         }
236         if(obj.getAttribute("bz")==undefined){
237             //debugger;
238             btnClick(jsr);
239         }
240         obj.setAttribute("bz","Y");
241         document.getElementById("childframe").contentWindow.hfxx(jsr,fsr,msg);
242     }
243 }
244 
245 function btnClick(jsr){
246     //alert(JSON.stringify(jsonObj2));
247     //debugger;
248     document.getElementById(jsr+"_span").style.display='none';
249     document.getElementById(jsr+"_span").innerHTML='';
250     window.frames["childframe"].document.getElementById("dhk").innerHTML = '';
251     localStorage.setItem('WSBS_PT_ZXBS_'+id, JSON.stringify(jsonObj2));
252     window.frames["childframe"].document.getElementById("uuid").setAttribute("fsrid",jsr);
253     window.frames["childframe"].document.getElementById("uuid").setAttribute("fsrmc",userOnLineMap.get(jsr));
254     document.getElementById("childframe").contentWindow.initLocalStorage(jsr,id);
255     
256     //alert(window.frames["childframe"].document.getElementById("uuid").getAttribute("fsrid"));
257 }
258 
259 //连接关闭的回调方法
260 websocket.onclose = function() {
261     localStorage.setItem('WSBS_PT_ZXBS_'+id, JSON.stringify(jsonObj2));
262     //localStorage.removeItem('WSBS_PT_ZXBS_'+id);
263     //setMessageInnerHTML("WebSocket连接关闭");
264 }
265 
266 //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
267 window.onbeforeunload = function() {
268     closeWebSocket();
269 }
270 
271 //关闭WebSocket连接
272 function closeWebSocket() {
273     websocket.close();
274 }
275 
276 function send(data) {//获取当前tab的id,即接收人
277     websocket.send(data);
278 }
其实其中重要的就是那几个JS方法,都写有注释。需要注意的是这里
1 //判断当前浏览器是否支持WebSocket
2 if ('WebSocket' in window) {
3     websocket = new WebSocket("ws://222.90.69.254:7001/mobile/websocket/"
4             + user+"/"+id+"/"+ptbz);
5 } else {
6     alert('当前浏览器 Not support websocket,请更换浏览器');
7 }

zxws.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport"
    content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0" />
<title>在线问税</title>
</head>
<script type="text/javascript" src="../zjzz/js/jquery-1.12.0.min.js"
    charset="utf-8"></script>
<script type="text/javascript" src="zxws.js" charset="utf-8"></script>
<style>
.org_box {
    float:left;
    text-align: left;
    font-family: "Microsoft YaHei", 微软雅黑;
    font-size: 16px;
    margin-top: 5px;
    height: auto;
    width: auto;
    max-width: 55%;
    line-height: 30px;
    border: 1px solid #E3E3E3;
    background: #F6F6F6;
    border-radius: 4px;
    padding: 5px;
    display:inline-block;
}

.org_div {
    margin-top: 8px;
    float: right;
    width: 100%;
    word-break: break-all;
}

.org_hf {
    float: right;
    border: 1px solid #87CEEB;
    background:#ACD9F8;
    border-radius: 4px;
    padding: 5px;
    height: auto;
    width: auto;
    line-height: 30px;
    max-width: 55%;
    word-break: break-all;
    display:inline-block;
    overflow: hidden;
    text-align: left;
}
.org_yh{
    float:right;
    height:20px;
    word-break: break-all;
}
.org_yh1{
    margin-top: 10px;
    float:left;
    height:auto;
    width:auto;
    word-break: break-all;
}
.org_sj1{
    float:right; 
    height:5px;
    font-size: 8px;
    word-break: break-all;
    text-align: left;
    border-radius: 4px;
    padding: 5px;
    margin-top: 0px;
}
.org_sj2{
    float:left; 
    height:5px;
    font-size: 8px;
    word-break: break-all;
    text-align: left;
    border-radius: 4px;
    padding: 0px;
    margin-top: 9px;
} 
* {
    margin: 0px;
    padding: 0px;
    list-style: none;
    box-sizing: border-box;
}

#zt {
    height: 516px;
}

#dhk {
    margin-top: 2px;
    height: 300px;
    width: 590px;
    overflow-Y: auto;
    border: 1px solid #e7eaf1;
    margin-left: 5px;
    margin-right: 5px;
}

#lts {
    height: 160px;
    overflow: auto;
    border: 1px solid #e7eaf1;
    margin-left: 5px;
    margin-right: 5px;
}

#gjl {
    height: 20%;
    overflow: auto;
}

#ltk {
    height: 79.5%;
    overflow: auto;
    border: 1px solid #e7eaf1;
    display: block;
    visibility: visible;
}

.close {
    position: absolute;
    top: 5px;
    right: 5px;
    z-index: 1000;
    width: 19px;
    height: 19px;
    cursor: pointer;
    -webkit-user-select: none;
}

.minisize {
    position: absolute;
    right: 38px;
    top: 4px;
    z-index: 1000;
    width: 19px;
    height: 19px;
    cursor: pointer;
    -webkit-user-select: none;
}

.fs {
    margin-left: 500px;;
    background: #0f88eb;
    width: 75px;
    color: #fff;
    border: 1px solid #0f88eb;
    cursor: pointer;
    display: inline-block;
    font-size: 14px;
    line-height: 32px;
    padding: 0 16px;
    text-align: center;
    float: left;
}

.qx {
    margin-left: 20px;;
    background: #0f88eb;
    width: 75px;
    color: #fff;
    border: 1px solid #0f88eb;
    cursor: pointer;
    display: inline-block;
    font-size: 14px;
    line-height: 32px;
    padding: 0 16px;
    text-align: center;
    float: left;
}

#bqb {
    position: absolute;
    width: 250px;
    border: 1px solid #e7eaf1;
    left: 30px;
    top: 300px;
    visibility: hidden;
}
</style>

<body>
        <!-- <button type="button" class="fs" onclick="localStorage.removeItem('WSBS_PT_ZXBS_'+id);" id=" ">清理</button> -->
    <div id="zt">
        <div id="bqb">
            <img src="biaoqing/1.png" style="width: 27px; height: 27px;"
                onclick="bqdj(1);" /> <img src="biaoqing/2.png"
                style="width: 27px; height: 27px;" onclick="bqdj(2);" /> <img
                src="biaoqing/3.png" style="width: 27px; height: 27px;"
                onclick="bqdj(3);" /> <img src="biaoqing/4.png"
                style="width: 27px; height: 27px;" onclick="bqdj(4);" /> <img
                src="biaoqing/5.png" style="width: 27px; height: 27px;"
                onclick="bqdj(5);" /> <img src="biaoqing/6.png"
                style="width: 27px; height: 27px;" onclick="bqdj(6);" />
        </div>
        <div id="dhk" style="background: #EEEEEE"></div>
        <div id="lts">
            <div id="gjl">
                <ul>
                    <li><img onclick="tjbq()" src="picture/1.png"
                        style="width: 27px; height: 27px; margin-left: 5px; margin-left: 5px;" /></li>
                </ul>
            </div>
            <div id="ltk" contenteditable="true" ></div>
        </div>
        <div style="margin-top: 3px;">
            <!-- <span id="subjectchk">还可输入 <strong id="checklen"
                style="color: #FF0000">400</strong> 个字符
            </span> -->
            <button type="button" class="fs" onclick="fsxx();" id="uuid">发送</button>
            <!-- <button type="button" class="qx" onclick="closewindow();">关闭</button> -->
        </div>
    </div>

</body>
</html>
zxws.js
  1 function fsxx() {
  2     var c = document.getElementById("ltk").innerHTML;
  3     var jsr = document.getElementById("uuid").getAttribute("fsrid");
  4     var fsrmc = document.getElementById("uuid").getAttribute("fsrmc");
  5     
  6     var now = new Date(); 
  7     var nowTime = now.toLocaleString(); 
  8     var date = nowTime.substring(0,10);//截取日期 
  9     var time = nowTime.substring(10,20);
 10     
 11     //var date = new Date();
 12     //var year = date.getFullYear();
 13     //var month = date.getMonth()+1;
 14     //var day = date.getDate();
 15     //var hour = date.getHours();
 16     //var minute = date.getMinutes();
 17     //var second = date.getSeconds();
 18     //alert(year+'年'+month+'月'+day+'日'+hour+':'+minute+':'+second);
 19     
 20     window.parent.send(jsr+"&@"+c);
 21     var c1 = document.getElementById("dhk");
 22     var div1 = document.createElement("div");
 23     div1.className = "org_div";
 24     var yhDiv = document.createElement("span");
 25     yhDiv.className = "org_yh";
 26     yhDiv.innerHTML = ":我";
 27     var newDiv = document.createElement("span");
 28     newDiv.className = "org_hf";
 29     var msg =  c ;
 30     newDiv.innerHTML = msg;
 31     var sjDiv = document.createElement("span");
 32     sjDiv.className = "org_sj1";
 33     var lrrq = nowTime;
 34     sjDiv.innerHTML = lrrq;
 35     var dataJson = {'fsr':window.parent.id,'jsr':jsr,'fsrmc':fsrmc,'dhnr':c,'lrrq':lrrq};
 36     updateLocalStorage(jsr,fsrmc,dataJson);
 37     div1.appendChild(yhDiv);
 38     div1.appendChild(newDiv);
 39     div1.appendChild(sjDiv);
 40     c1.appendChild(div1);
 41     /*var c2 = document.createElement("br");
 42     c1.appendChild(c2);*/
 43     document.getElementById("ltk").innerHTML = "";
 44     c1.scrollTop = c1.scrollHeight;
 45 }
 46 function hfxx(jsr,fsr,data) {
 47     var a = document.getElementById("uuid").getAttribute("fsrid");
 48     var fsrmc = document.getElementById("uuid").getAttribute("fsrmc");
 49     //var d = document.getElementById("time").innerHTML;
 50     
 51     var now = new Date(); 
 52     var nowTime = now.toLocaleString(); 
 53     var date = nowTime.substring(0,10);//截取日期 
 54     var time = nowTime.substring(10,20);
 55     //var date = new Date();
 56     //var year = date.getFullYear();
 57     //var month = date.getMonth()+1;
 58     //var day = date.getDate();
 59     //var hour = date.getHours();
 60     //var minute = date.getMinutes();
 61     //var second = date.getSeconds();
 62     //alert(year+'年'+month+'月'+day+'日'+hour+':'+minute+':'+second);
 63     
 64     if(a==jsr) {
 65         var c1 = document.getElementById("dhk");
 66         var div1 = document.createElement("div");
 67         div1.className = "org_div";
 68         var yhDiv = document.createElement("span");
 69         yhDiv.className = "org_yh1";
 70         yhDiv.innerHTML = fsr+":";
 71         var newDiv = document.createElement("span");
 72         newDiv.className = "org_box";
 73         newDiv.innerHTML = data;
 74         var sjDiv = document.createElement("span");
 75         sjDiv.className = "org_sj2";
 76         var lrrq = nowTime;
 77         sjDiv.innerHTML = lrrq;
 78         div1.appendChild(yhDiv);
 79         div1.appendChild(newDiv);
 80         div1.appendChild(sjDiv);
 81         c1.appendChild(div1);
 82         /*var c2 = document.createElement("br");
 83         c1.appendChild(c2);*/
 84         c1.scrollTop = c1.scrollHeight;
 85         var dataJson = {'fsr':a,'jsr':window.parent.id,'fsrmc':fsr,'dhnr':data,'lrrq':lrrq};
 86         updateLocalStorage(a,fsrmc,dataJson);
 87     }else if(a=="系统"){
 88         var c1 = document.getElementById("dhk");
 89         var div1 = document.createElement("div");
 90         div1.className = "org_div";
 91         var newDiv = document.createElement("span");
 92         newDiv.className = "org_box";
 93         newDiv.innerHTML = data;
 94         div1.appendChild(newDiv);
 95         c1.appendChild(div1);
 96         /*var c2 = document.createElement("br");
 97         c1.appendChild(c2);*/
 98         c1.scrollTop = c1.scrollHeight;
 99     }
100 }
101 //更新对话json串
102 var jsonObj1 = window.parent.jsonObj2;
103 function updateLocalStorage(jsr,fsr,data) {
104     //debugger;
105     var str = jsr+"@"+fsr;
106     if(jsonObj1[str]==undefined) {
107         var temp = [];
108         jsonObj1[str] = temp;
109         jsonObj1[str].push(data);
110     }else{
111         jsonObj1[str].push(data);
112     }
113 }
114 function initLocalStorage(jsr,id) {
115     jsonObj1 = window.parent.jsonObj2;
116     var fsrid = document.getElementById("uuid").getAttribute("fsrid");
117     var fsrmc = document.getElementById("uuid").getAttribute("fsrmc");
118     var str = fsrid+"@"+fsrmc;
119     var jsonStr = localStorage.getItem('WSBS_PT_ZXBS_'+id);
120     if(jsonStr==null||jsonStr.length==0) {
121         
122     }else{
123         var jsonMsg = JSON.parse(jsonStr);
124         if(jsonMsg[str]!=undefined) {
125             var jsrMsg = jsonMsg[str];
126             for (var i = 0; i < jsrMsg.length; i++) {
127                 var fsr = jsrMsg[i].fsr;
128                 if(fsr==fsrid) {
129                     var c1 = document.getElementById("dhk");
130                     var div1 = document.createElement("div");
131                     div1.className = "org_div";
132                     var yhDiv = document.createElement("span");
133                     yhDiv.className = "org_yh1";
134                     yhDiv.innerHTML = jsrMsg[i].fsrmc+":";
135                     var newDiv = document.createElement("p");
136                     newDiv.className = "org_box";
137                     newDiv.innerHTML = jsrMsg[i].dhnr;
138                     var sjDiv = document.createElement("span");
139                     sjDiv.className = "org_sj2";
140                     sjDiv.innerHTML = jsrMsg[i].lrrq;
141                     div1.appendChild(yhDiv);
142                     div1.appendChild(newDiv);
143                     div1.appendChild(sjDiv);
144                     c1.appendChild(div1);
145                     c1.scrollTop = c1.scrollHeight;
146                 }else{
147                     var c1 = document.getElementById("dhk");
148                     var div1 = document.createElement("div");
149                     div1.className = "org_div";
150                     var yhDiv = document.createElement("span");
151                     yhDiv.className = "org_yh";
152                     yhDiv.innerHTML = ":我";
153                     var newDiv = document.createElement("p");
154                     newDiv.className = "org_hf";
155                     newDiv.innerHTML = jsrMsg[i].dhnr;
156                     var sjDiv = document.createElement("span");
157                     sjDiv.className = "org_sj1";
158                     sjDiv.innerHTML = jsrMsg[i].lrrq;
159                     div1.appendChild(yhDiv);
160                     div1.appendChild(newDiv);
161                     div1.appendChild(sjDiv);
162                     c1.appendChild(div1);
163                     c1.scrollTop = c1.scrollHeight;
164                 }
165             }
166         }
167     }
168 }
169 
170 function tjbq() {
171     if(bqb.style.visibility=='visible'){
172         bqb.style.visibility="hidden";
173     }else{
174         bqb.style.visibility="visible";
175     }
176 }
177 
178 function hiddenBq() {
179     var bqb = document.getElementById("bqb");
180     bqb.style.visibility = "hidden";
181 }
182 
183 function bqdj(num) {
184     var imgsrc = "biaoqing/" + num + ".png";
185     showImg(imgsrc);
186     hiddenBq();
187 }
188 
189 function showImg(imgsrc) {
190     var img = document.createElement("img");
191     img.src = imgsrc;
192     //img.onselectstart= function(){return false;}
193     var parent = document.getElementById("ltk");
194     var div = document.createElement("div");
195     div.appendChild(img);
196     div.style.display = 'inline-block';
197     div.onselectstart= function(){return false;}
198     parent.appendChild(div); 
199 }
200 function getByteLen(val) {
201     var len = 0;
202     for (var i = 0; i < val.length; i++) {
203       var a = val.charAt(i);
204       if (a.match(/[^\x00-\xff]/ig) != null) {
205         len += 2;
206       }
207       else {
208         len += 1;
209       }
210     }
211     return len;
212   }
213   // 只要键盘一抬起就验证编辑框中的文字长度,最大字符长度可以根据需要设定
214   function checkLength(obj) {
215           var a = document.getElementById("ltk");
216         debugger;
217         var maxChars = 400;//最多字符数   
218         var curr = maxChars - getByteLen(obj.innerHTML);
219         if (curr > 0) {
220           document.getElementById("checklen").innerHTML = curr.toString();
221         } else {
222           document.getElementById("checklen").innerHTML = '0';
223           document.getElementById("ltk").readOnly = true;
224           var oBtn = document.getElementById('fs');
225           oBtn.onclick = function(){
226               oBtn.disabled = 'disabled';
227           };
228         }
229   }
230   
231   /**
232      * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
233      * 
234      * @param message
235      * @throws IOException
236      */
237   function xxql() {
238         this.session.getBasicRemote().sendText(message);
239         /*if("pt".equals(this.currentUserVo.getPtbz())) {
240             webSocketSetPt.remove(this.webSocketMap);
241         }else{
242             webSocketSet.remove(this.webSocketMap); // 从set中删除
243         }
244         subOnlineCount(); // 在线数减
245         System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());*/
246     }
247   

注意:最后要在web-info下lib文件夹下引入websocket-api.jar,这样打war包才不会出错