웹 소켓 을 이용 하여 안 드 로 이 드 메시지 전송 실현

얼마 전에 프로젝트 를 만 들 려 면 안 드 로 이 드 클 라 이언 트 가 관리 도구 로 서 웹 서버 배경 과 실시 간 으로 상호작용 을 해 야 합 니 다.안 드 로 이 드 pn,openfire+smack,xmpp 프로 토 콜 을 포함 하여 여러 가지 방법 을 생각 했 습 니 다.너무 번 거 롭 거나 실시 성 을 만족 시 킬 수 없습니다.아무래도 socket 을 사용 하 는 것 이 좋 겠 습 니 다.알림 을 받 아 websocket 이 생각 났 습 니 다.
    웹 소켓 프로 토 콜 은 최근 몇 년 동안 html 5 의 발전 에 따라 탄생 한 것 으로 주로 웹 서버 와 클 라 이언 트 가 서로 상호작용 할 수 없 는 문 제 를 해결 하 는 데 사용 된다.지금 은 W3C 수입 표준 에 의 해 협의 되 었 다.
    서버 지원:tomcat,jetty 의 최신 버 전 은 모두 websocket 을 지원 합 니 다.기 존 서버 를 교체 하지 않 으 려 면 spring 4.0 으로 대체 할 수도 있다.새 버 전의 jre 는 웹 소켓 류 에 들 어 갈 것 이 라 고 하 며 구체 적 으로 접촉 하지 않 았 다.
    클 라 이언 트 지원:현재 주류 브 라 우 저 는 모두 websocket 을 실 현 했 지만 초기 프로 토 콜 버 전의 변화 가 너무 빨 라 서 많은 업 체 들 이 따라 가지 못 했 습 니 다.안 드 로 이 드 기본 브 라 우 저 는 웹 소켓 을 지원 하지 않 고 IE 도 IE 10 에 이 르 러 서 야 지원 합 니 다.
    인터넷 에 html 를 통 해 웹 소켓 client 를 실현 하 는 예 가 있 습 니 다.여기 서 자바 로 클 라 이언 트 연결 을 실현 합 니 다.잔말 말고 데모 에 오 르 세 요.
1.서버 쪽
서버 는 tomcat 7.0 을 사용 하여 tomcat 의 websocket 을 직접 사용 하여 실현 합 니 다.
(1)연결 관리 클래스
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.List;
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.WsOutbound;
 
public class MessageCenter
{
    private static MessageCenter        instance           = new MessageCenter();
 
    private List<MessageInbound>        socketList;
 
    private MessageCenter()
    {
        this.socketList = new ArrayList<MessageInbound>();
    }
 
    public static MessageCenter getInstance()
    {
        return instance;
    }
 
    public void addMessageInbound(MessageInbound inbound)
    {
        socketList.add(inbound);
    }
 
    public void removeMessageInbound(MessageInbound inbound)
    {
        socketList.remove(inbound);
    }
 
    public void broadcast(CharBuffer msg) throws IOException
    {
        for (MessageInbound messageInbound : socketList)
        {
            CharBuffer buffer = CharBuffer.wrap(msg);
            WsOutbound outbound = messageInbound.getWsOutbound();
            outbound.writeTextMessage(CharBuffer.wrap("broadcasting:" + msg));
            // outbound.writeTextMessage(buffer);
            outbound.flush();
        }
    }
}

(2)메시지 입구 클래스
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.Date;
 
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.WsOutbound;
 
public class MyMessageInbound extends MessageInbound {
 
    @Override
    protected void onBinaryMessage(ByteBuffer arg0) throws IOException {
        // TODO Auto-generated method stub
         
    }
 
    @Override
    protected void onTextMessage(CharBuffer msg) throws IOException {
        System.out.println("Received:"+msg);
        MessageCenter.getInstance().broadcast(msg);
         
    }
 
    @Override
    protected void onClose(int status) {
        System.out.println("close:"+new Date());
        MessageCenter.getInstance().removeMessageInbound(this);
        super.onClose(status);
    }
 
    @Override
    protected void onOpen(WsOutbound outbound) {
        System.out.println("open :"+new Date());
        super.onOpen(outbound);
        MessageCenter.getInstance().addMessageInbound(this);
    }
}

(3)Websocket servlet
import javax.servlet.http.HttpServletRequest;
 
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
 
public class MeWebSocketServlet extends WebSocketServlet
{
 
    private static final long serialVersionUID = -7178893327801338294L;
 
    @Override
    protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest request)
    {
        System.out.println("##########client login#########");
        return new MeMessageInbound();
    }
 
}

(4)servlet 를 웹.xml 에 추가 합 니 다.
  < servlet>
               < servlet-name> android</ servlet-name >
               < servlet-class> MyWebSocketServlet </servlet-class >
        </ servlet>
        < servlet-mapping>
               < servlet-name> android</ servlet-name >
               < url-pattern> *.do</ url-pattern >
        </ servlet-mapping>

2.클 라 이언 트
    클 라 이언 트 는 자바 를 사용 하여 웹 소켓 client 를 실현 합 니 다.
    인터넷 에서 자바-websocket 을 실현 한 사람 이 있 습 니 다.https://github.com/TooTallNate/Java-WebSocket 
원본 코드 를 얻 을 수 있 습 니 다.maven 으로 컴 파일 할 수 있 습 니 다.
    최신 jar 패키지 다운로드 주소:
     http://download.csdn.net/detail/chifengxin/6524283
    jar 패 키 지 를 참조 한 후 간단 한 메시지 연결 을 실현 합 니 다:
import java.net.URI;
import java.net.URISyntaxException;
 
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_10;
import org.java_websocket.drafts.Draft_17;
import org.java_websocket.framing.Framedata;
import org.java_websocket.handshake.ServerHandshake;
 
/** This example demonstrates how to create a websocket connection to a server. Only the most important callbacks are overloaded. */
public class ExampleClient extends WebSocketClient {
 
        public ExampleClient( URI serverUri , Draft draft ) {
                super( serverUri, draft );
        }
 
        public ExampleClient( URI serverURI ) {
                super( serverURI );
        }
 
        @Override
        public void onOpen( ServerHandshake handshakedata ) {
                System.out.println( "opened connection" );
                // if you plan to refuse connection based on ip or httpfields overload: onWebsocketHandshakeReceivedAsClient
        }
 
        @Override
        public void onMessage( String message ) {
                System.out.println( "received: " + message );
        }
 
        @Override
        public void onFragment( Framedata fragment ) {
                System.out.println( "received fragment: " + new String( fragment.getPayloadData().array() ) );
        }
 
        @Override
        public void onClose( int code, String reason, boolean remote ) {
                // The codecodes are documented in class org.java_websocket.framing.CloseFrame
                System.out.println( "Connection closed by " + ( remote ? "remote peer" : "us" ) );
        }
 
        @Override
        public void onError( Exception ex ) {
                ex.printStackTrace();
                // if the error is fatal then onClose will be called additionally
        }
 
        public static void main( String[] args ) throws URISyntaxException {
                ExampleClient c = new ExampleClient( new URI( "ws://localhost:8080/myweb/android.do" ), new Draft_17() );
                c.connect();
        }
 
}

웹 소켓 의 장단 점 을 정리 하 다.
장점:
socket 에 비해 추가 포트 점용 을 절약 하고 네트워크 도 메 인 이름 으로 직접 접근 할 수 있 습 니 다.또한 협 의 는 메시지 의 유량 소 모 를 최적화 시 켰 다.
단점:
웹 소켓 바 텀 도 socket 연결 이기 때문에 동시 다발 사용자 가 연결 할 때 눈대중 이 많은 자원 을 소모 할 수 있 습 니 다.
참고:
Tomcat 7.0 api  http://tomcat.apache.org/tomcat-7.0-doc/api/
출처:http://blog.csdn.net/chifengxin/article/details/14521093

좋은 웹페이지 즐겨찾기