java服务端与Android客户端使用 websocket 通信

最近因为项目需要所以得使用 websocket 来进行服务器与客户端的通信。使用java 来实现服务端,Android 实现客户端。

刚开始服务端使用 @ServerEndPoint 注解来实现 Websocket 服务端,但是 Android 使用的是 autobahn 实现的客户端,所以一直连接不上,报错为:WebSockets protocol violation 。 

后面我把服务端改为使用 @WebServlet 注解,并继承 WebSocketServlet 类来实现,然后就成功连接了。

这是修改之前的:

import org.apache.commons.fileupload.FileItem;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/socketServerTest")
public class SocketServer {
    private int maxFileSize = 1024 * 1024 * 10;
    private  String userId;
    private Session session;
    public static Map clients=new ConcurrentHashMap<>();
    //连接时执行
    @OnOpen
     public void onOpen(  Session session){
        System.out.println("新连接:"+userId);
        this.userId="test";
        userId="test";
        this.session=session;
        //把本连接加入到clients中
        clients.put(userId,this);

    }

    //关闭时执行
    @OnClose
    public void onClose(){
        System.out.println("连接关闭");
    }

    //收到消息时执行
    @OnMessage
    public void OnMessage(String message,Session session) throws IOException, EncodeException {
        session.getBasicRemote().sendText("收到用户:"+userId+"的消息:"+message);
        if(message.startsWith("response:")){
            String substring = message.substring(9);
            //如果app选择接受则发送文件
            if(substring.equals("accept")){
                FileItem fileItem = SendFileServlet.fileMap.get(userId);
                sendFileToUser(this.userId,fileItem);
            }else {
                System.out.println("用户拒绝接受文件");
            }
        }
        System.out.println("消息:"+message);
    }

    //连接错误时执行
    @OnError
    public void onError(Session session,Throwable error){
        System.out.println("错误:"+error);
    }

    //给用户发送文件
    public void sendFileToUser(String userId, FileItem fileItem) throws IOException, EncodeException {
        SocketServer socketServer = clients.get(userId);
        if(socketServer!=null) {
            byte[] fileStream = new byte[maxFileSize];
            fileItem.getOutputStream().write(fileStream);
            socketServer.session.getBasicRemote().sendBinary(ByteBuffer.wrap(fileStream));
        }
        else {
            System.out.println("该用户未连接");
        }
    }

    public void askAcceptFile(String userId,FileItem fileItem) throws IOException {
        SocketServer socketServer= clients.get(userId);
        if(socketServer!=null){
            byte[] bytes = fileItem.get();
            socketServer.session.getBasicRemote().sendText("ask,"+"file:");
            socketServer.session.getBasicRemote().getSendStream().write(bytes);
        }
        else {
            System.out.println("该用户未连接");
        }
    }
}

修改之后的:

import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
import org.apache.catalina.websocket.WsOutbound;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.Set;

@WebServlet("/socket") //服务名称
public class AnSocketServer extends WebSocketServlet {
    /**
     *
     */
    private static final long serialVersionUID = -1058445282919079067L;


    protected StreamInbound createWebSocketInbound(String s,HttpServletRequest request) {
        return new ChatMessageInbound();
    }

    @Override
    protected StreamInbound createWebSocketInbound(String s) {
        return new ChatMessageInbound();
    }

    class ChatMessageInbound extends MessageInbound {

        public ChatMessageInbound(){

        }
        @Override
        protected void onOpen(WsOutbound outbound) {
            super.onOpen(outbound);
            System.out.println("!!!!!123123123");
        }

        @Override
        protected void onClose(int status) {
            super.onClose(status);
            System.out.println("断开连接");
        }

        @Override
        protected void onBinaryMessage(ByteBuffer buffer) throws IOException {
            // TODO Auto-generated method stub  

        }

        @Override
        protected void onTextMessage(CharBuffer buffer) throws IOException {
            String msg = buffer.toString();  //接受客户端消息
        }

        @Override
        public int getReadTimeout() {
            return 0;
        }
    }
}

经过思考,我认为是使用的协议不一致导致的。

你可能感兴趣的:(Java学习,计算机网络)