如何基于BS架构开发聊天程序

来源:互联网 发布:linux服务器搭建 编辑:程序博客网 时间:2024/05/17 23:44

最近经常看到关于“如何基于BS架构开发聊天程序”的问题,这里把写的一个简要实例代码贴出来。


那么BS的聊天系统,一般两种技术(各有优劣):
1、基于Ajax或子页面刷新的拉模型;
2、基于HTTP长连接的推模型。

因为Ajax的“拉模型”,比较常见,这里给出基于HTTP长连接的“推模型”:


由三个页面组成:
chatmain.jsp 框架页面,引入两个Frame页面,并负责创建聊天室;
chatwnd.jsp 聊天信息窗口,负责用服务器推的方式显示所有人的聊天信息;
chatsender.jsp 聊天发送窗口,负责发送自己想说的话。


注意:本样例主要是为了说明 “基于长连接的推模型”,在聊天室完备性上完全不具有参考意义。


【chatmain.jsp 框架页面】

[html] view plaincopy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  
  2. <%@ page import="java.util.*"%>  
  3. <%  
  4.     // 这三句话只是为了防止浏览器缓存  
  5.     response.setHeader("Cache-Control", "no-cache, no-store"); //HTTP 1.1    
  6.     response.setHeader("Pragma", "no-cache"); //HTTP 1.0    
  7.     response.setDateHeader("Expires", 0); //prevents caching at the proxy server  
  8.   
  9.   
  10.     // 检查并按需创建“聊天室”  
  11.     ArrayList<String> lstMsg = (ArrayList<String>) application.getAttribute("room");  
  12.     if (lstMsg == null) {  
  13.         application.setAttribute("room", new ArrayList<String>());  
  14.     }  
  15. %>  
  16. <html>  
  17. <frameset rows="80%, 20%">  
  18.   <frame src="chatwnd.jsp"></frame>  
  19.   <frame src="chatsender.jsp"></frame>  
  20. </frameset>  
  21. </html>  



【chatwnd.jsp 聊天信息窗口】

[html] view plaincopy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>    
  2. <%@ page import="java.util.*"%>    
  3. <%@ page import="java.io.*"%>    
  4. <html>  
  5. <h2>Welcome to the ChatRoom!</h2>  
  6. <%  
  7.     // 这三句话只是为了防止浏览器缓存  
  8.     response.setHeader("Cache-Control", "no-cache, no-store"); //HTTP 1.1      
  9.     response.setHeader("Pragma", "no-cache"); //HTTP 1.0      
  10.     response.setDateHeader("Expires", 0); //prevents caching at the proxy server    
  11.   
  12.   
  13.     Integer myMsgPos = 0; // 记录最后显示消息的位置  
  14.     ArrayList<String> lstMsg = (ArrayList<String>) application.getAttribute("room");  
  15.     out.flush(); // 把之前的HTML信息都刷出去  
  16.     PrintWriter pw = response.getWriter(); // 用PrintWriter取代JspWriter以便于检查Socket异常  
  17.     try {    
  18.         synchronized (lstMsg) {    
  19.             while (true) { // 死循环,也就意味着本次HTTP请求不会结束  
  20.                 if (lstMsg.size() > myMsgPos) { // 检查有没有新的消息  
  21.                     // 循环显示所有新消息  
  22.                     System.out.println("Got new msg to push: "+(lstMsg.size()-myMsgPos));  
  23.                     for (int i = myMsgPos; i < lstMsg.size(); i++) {    
  24.                         String msg = lstMsg.get(i);  
  25.                         pw.write("<p>"+msg+"</p>");  
  26.                     }  
  27.                     if (pw.checkError()) { // 强制将输出缓冲区内容发送出去,并检查异常  
  28.                         System.out.println("IOException detected, JSP end.");  
  29.                         break; // 说明已经发生IOException(一般是浏览器页面关掉了)  
  30.                     }  
  31.                     myMsgPos = lstMsg.size(); // 更新最后显示的消息位置  
  32.                 }  
  33.                 System.out.println("Waiting new msg..." + out.getRemaining());  
  34.                 lstMsg.wait(); // 临时释放对lstMsg的独占(同步锁),等待新消息的到来  
  35.             }  
  36.         }  
  37.     } catch (Exception ex) {    
  38.         System.out.println(ex);    
  39.     }  
  40. %>  
  41. </html>  




【chatsender.jsp 聊天发送窗口】

[html] view plaincopy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>    
  2. <%@ page import="java.util.*" %>    
  3. <%@ page import="java.text.*" %>      
  4. <%  
  5.     SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");  
  6.     // 这三句话只是为了防止浏览器缓存  
  7.     response.setHeader("Cache-Control", "no-cache, no-store"); //HTTP 1.1  
  8.     response.setHeader("Pragma", "no-cache"); //HTTP 1.0      
  9.     response.setDateHeader("Expires", 0); //prevents caching at the proxy server  
  10.   
  11.   
  12.     // 获取POST的“发言”      
  13.     String msg = request.getParameter("msg");    
  14.     if (msg!=null && msg.length()>0) {    
  15.         msg = "[" + sdf.format(new Date()) + "]" + session.getId() + ": " + msg;     
  16.         System.out.println(msg); // 调试跟踪用的信息  
  17.         ArrayList<String> lstMsg = (ArrayList<String>) application.getAttribute("room");    
  18.         synchronized (lstMsg) {  
  19.             lstMsg.add(msg); // 消息放入池中(消息太多会溢出的,这里并没有进行处理)  
  20.             lstMsg.notifyAll(); // 通知chatwnd.jsp们,有新的消息来了,可以推给浏览器了  
  21.         }  
  22.     }  
  23. %>    
  24. <!DOCTYPE unspecified PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">    
  25. <html>    
  26. <form method="post">    
  27.     My Speak: <input name="msg" type="text" size="40" /> <input type="submit" />    
  28. </form>    
  29. </html>  

0 0
原创粉丝点击