1 <dependency> 2 <groupId>org.apache.tomcat</groupId> 3 <artifactId>tomcat-coyote</artifactId> 4 <version>7.0.39</version> 5 </dependency> 6 <dependency> 7 <groupId>org.apache.tomcat</groupId> 8 <artifactId>tomcat-catalina</artifactId> 9 <version>7.0.39</version>10 </dependency>11 <dependency>12 <groupId>org.apache.tomcat</groupId>13 <artifactId>tomcat-annotations-api</artifactId>14 <version>7.0.39</version>15 </dependency>
接下來是解決架構問題。現在在網上能搜到關於websocket的實踐很少,基本能搜到的都是websocket架構和非常簡單的例子(tomcat自帶就有websocket例子),怎麽樣能將websocket機制運用起來。首先基本框架準備使用hibernate+spring mvc結合websocket,但是在實際試驗中spring mvc和websocket會有部分有沖突。因為到前壹段時間Spring Framework 4.0發布的版本中才有了JDK 8的支持和WebSocket編程的支持。所以現階段需要別的方式來實現spring mvc+websocket。簡單的解決方案就是寫壹個工具類來手動獲得bean。解決spring和websocket支持之後需要解決的websocket的交互方式。websocket最直接的兩個方法就是onTextMessage和onBinaryMessage,也就是字節流傳輸和字符流傳輸。最優方式便是設計壹套自己傳輸協議。通過字節流傳輸。前後臺分別解析協議獲取交互操作。其次便可在onTextMessage也就是字符流上做文章。引入json便可以很好支持了。
配置websocket的步驟:
1實現壹個類繼承ContextLoaderListener,並且在web.xml中配置
1 import javax.servlet.ServletContext; 2 import javax.servlet.ServletContextEvent; 3 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.web.context.ContextLoaderListener; 6 import org.springframework.web.context.support.WebApplicationContextUtils; 7 8 public class SpringLoaderListener extends ContextLoaderListener{ 9 10 @Override11 public void contextInitialized(ServletContextEvent event) {12 super.contextInitialized(event);13 ServletContext context=event.getServletContext();14 ApplicationContext ctx=WebApplicationContextUtils.getRequiredWebApplicationContext(context);15 SpringContextutil.setContext(ctx);16 17 }18 19 }
web.xml
1 <listener>2 <listener-class>3 XXXXXX.utils.SpringLoaderListener4 </listener-class>5 </listener>
獲得spring bean工具類:
1 import org.springframework.beans.BeansException; 2 import org.springframework.beans.factory.NoSuchBeanDefinitionException; 3 import org.springframework.context.ApplicationContext; 4 5 public class SpringContextUtil { 6 private static ApplicationContext context; 7 8 public static ApplicationContext getContext() { 9 return context;10 }11 12 public static void setContext(ApplicationContext context) {13 SpringContextutil.context = context;14 }15 16 public static Object getBean(String name)throws BeansException{17 return context.getBean(name);18 }19 20 @SuppressWarnings("unchecked")21 public static Object getBean(String name, Class requiredType) throws BeansException { 22 return context.getBean(name, requiredType); 23 } 24 25 public static boolean containsBean(String name) { 26 return context.containsBean(name); 27 } 28 29 public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { 30 return context.isSingleton(name); 31 } 32 33 @SuppressWarnings("unchecked")34 public static Class getType(String name) throws NoSuchBeanDefinitionException { 35 return context.getType(name); 36 } 37 38 public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { 39 return context.getAliases(name); 40 } 41 42 43 }
引入json所需jar包:
1 <dependency> 2 <groupId>com.google.code.gson</groupId> 3 <artifactId>gson</artifactId> 4 <version>2.2.3</version> 5 </dependency> 6 <dependency> 7 <groupId>net.sf.json-lib</groupId> 8 <artifactId>json-lib</artifactId> 9 <version>2.4</version>10 </dependency>11 <dependency>12 <groupId>net.sf.ezmorph</groupId>13 <artifactId>ezmorph</artifactId>14 <version>1.0.6</version>15 </dependency>
後臺需要增加兩個文件壹個繼承WebSocketServlet:
1 import javax.servlet.annotation.WebServlet; 2 import javax.servlet.mandDispatcher; 5 6 public RoomMessageInbound() { 7 if (commandDispatcher == null) { 8 commandDispatcher = (CommandDispatcherUtils) SpringContextutil.getBean("commandDispatcher"); 9 room = RoomListModel.getInstance().getRoom(0);10 }11 }12 13 14 @Override15 protected void onOpen(WsOutbound outbound) 16 room.addUser(outbound.hashCode());17 super.onOpen(outbound);18 }19 20 @Override21 protected void onClose(int status) {22 room.remove(getWsOutbound().hashCode());23 super.onClose(status);24 }25 26 @Override27 protected void onBinaryMessage(ByteBuffer buffer) throws IOException {28 29 }30 31 @Override32 protected void onTextMessage(CharBuffer buffer) throws IOException {33 String msg = buffer.toString();34 JSONObject report = JSONObject.fromObject(msg);35 TemplateCommand command = commandDispatcher.getCommandByKey(report.getString("command"));36 command.execute(msg,user,room);37 }38 39 }
通過JSONObject report = JSONObject.fromObject(msg)就可以將字符串轉換為json對象。也就等於通過websocket實現了實時對象信息的傳遞。
在前端頁面中只需要頁面載入時的js中加入
1 $(function() { 2 roomsocket = new WebSocket('ws://127.0.0.1:8080/XXXX/room);3 }
在前端向後臺發送時將數據JSON.stringify(data)就能json化。
上述代碼做了不少刪減。所以代碼不見得復制就能用。只是提供壹種解決方案。況且不久java新的版本或者說Spring Framework 4.0就能很輕松的支持了websocket的實現。主要是還是給自己這段時間的websocket研究做壹些總結。隨著各種新的技術的誕生,實時web技術已經越來越成熟。websocket是html5的重要特色是值得去看看,研究壹下