最近在作一個APP的服務器端,可是APP和服務器端使用的是HTTP的通訊協議,而另外一方與服務器端通訊卻使用的是自定義的通訊協議。具體的系統拓撲以下:java
爲了完成以上的需求,通常的解決方案有兩種:web
本身實現服務器端程序,利用已經實現的http jar包來實現http通訊協議,同時利用socket通訊來實現本身的通訊協議;tomcat
將socket通訊整合在tomcat中,利用tomcat來提供http通訊,同時實現本身的通訊協議。服務器
對於第一種方法,全部的都須要本身來實現,須要本身進行環境的初始化,配置管理,比較麻煩。目前爲了方便開發,快速利用web的各類框架,採用的是第二種方法,將socket通訊整合在tomcat環境下,隨着web的啓動,初始化一個socketserver來進行自定義的數據通訊。app
在web環境下,tomcat整合socket的主要的難處就是如何觸發socket服務器的初始化,等待接受來自客戶端的鏈接,且socket服務器的初始化應該只初始化一次。在web啓動的時候,toncat會加載 context-param -> listener -> filter -> servlet,因此就能夠在這些類中來初始化socket服務來進行通訊。因而就新建一個SocketServlet並在框架
public void init(ServletConfig config) throws ServletException
方法中初始化一個ECHO Server的SocketServer來進行通訊socket
// TODO Auto-generated method stub System.out.println("this is the socket program ----zhangwenwen"); try { ServerSocket serverSocket=new ServerSocket(8191); socket=serverSocket.accept(); InputStream inputStream=socket.getInputStream(); OutputStream outputStream=socket.getOutputStream(); Scanner in=new Scanner(inputStream); PrintWriter printWriter=new PrintWriter(outputStream); printWriter.write("Hello Enter BYE to exit!"); boolean done=false; while(!done&&in.hasNextLine()){ String line=in.nextLine(); System.out.println(line); printWriter.println("ECHO:"+line); printWriter.flush(); if (line.trim().equals("BYE")) { done=true; } } in.close(); inputStream.close(); outputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
在web.xml中配置:ide
<servlet> <servlet-name>socketdemo</servlet-name> <servlet-class>SocketServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>socketdemo</servlet-name> <url-pattern>/demo</url-pattern> </servlet-mapping>
可是在啓動時候卻由於SocketServer一直在運行,Init方法運行不能返回,從而ServletSocket不能運行結束,tomcat最後會由於啓動失敗而退出。ui
於是,如今爲了解決這個問題,因而就將SocketServer封裝在一個線程中this
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; import javax.servlet.annotation.WebFilter; import sun.print.resources.serviceui; public class SocketDemo extends Thread { private static Socket socket=null; public static Socket getSocket() { return socket; } @Override public void run() { // TODO Auto-generated method stub System.out.println("this is the socket program ----zhangwenwen"); try { ServerSocket serverSocket=new ServerSocket(8191); socket=serverSocket.accept(); InputStream inputStream=socket.getInputStream(); OutputStream outputStream=socket.getOutputStream(); Scanner in=new Scanner(inputStream); PrintWriter printWriter=new PrintWriter(outputStream); printWriter.write("Hello Enter BYE to exit!\n"); printWriter.flush(); boolean done=false; while(!done&&in.hasNextLine()){ String line=in.nextLine(); System.out.println(line); printWriter.println("ECHO:"+line); printWriter.flush(); if (line.trim().equals("BYE")) { done=true; } } in.close(); inputStream.close(); outputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
而後在Init方法裏面在啓動一個線程來初始化SocketServer:
/** * @see Servlet#init(ServletConfig) */ public void init(ServletConfig config) throws ServletException { SocketDemo socketDemo=new SocketDemo(); socketDemo.start(); this.socket=socketDemo.getSocket(); }
這樣就實現了在tomcat下進行,在控制檯下用telnet進行訪問: