1. 程式人生 > >java 後端實現WebSocket學習篇和客戶端Android 通訊

java 後端實現WebSocket學習篇和客戶端Android 通訊

1.建立SpringBoot Java web 專案這裡當你已經熟悉Springboot

2,引入需要的WebSocket maven依賴

org.springframework.boot spring-boot-starter-websocket 3.配置webSocket

package com.gsc.websocket.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**

  • 配置websocket並開啟
    */
    @Configuration
    public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
    return new ServerEndpointExporter();
    }
    }

4 配置客戶端URL 訪問地址

客戶端URI訪問的路徑

package com.gsc.websocket.demo;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;

@ServerEndpoint("/websocket/{vmcNo}") // 客戶端URI訪問的路徑
@Component
public class WebSocketServer {
/**
* 儲存所有連線的webSocket實體
* CopyOnWriteArrayList使用了一種叫寫時複製的方法,
* 當有新元素新增到CopyOnWriteArrayList時,
* 先從原有的陣列中拷貝一份出來,然後在新的陣列做寫操作,
* 寫完之後,再將原來的陣列引用指向到新陣列。
* 具備執行緒安全,並且適用於高併發場景
*/
private static CopyOnWriteArrayList sWebSocketServers = new CopyOnWriteArrayList<>();
private Session mSession; // 與客戶端連線的會話,用於傳送資料
private long mVmcNo; // 客戶端的標識(這裡以機器編號)
private Log mLog = LogFactory.getLog(WebSocketServer.class);

@OnOpen
public void onOpen(Session session, @PathParam("vmcNo") long vmcNo) {
    mSession = session;
    sWebSocketServers.add(this); // 將回話儲存
    mLog.info("-->onOpen new connect vmcNo is " + vmcNo);
    mVmcNo = vmcNo;
}

@OnClose
public void onClose() {
    sWebSocketServers.remove(this);
    mLog.info("-->onClose a connect");
}

@OnMessage
public void onMessage(String message, Session session) {
    mLog.info("-->onMessage " + message);

// 這裡選擇的是讓其他客戶端都知道訊息,類似於轉發的聊天室,可根據使用場景使用
for (WebSocketServer socketServer : sWebSocketServers) {
socketServer.sendMessage(“i have rcv you message”);
}
}

/**
 * 對外發送訊息
 *
 * @param message
 */
public boolean sendMessage(String message) {
    try {
        mSession.getBasicRemote().sendText(message);
    } catch (IOException e) {
        mLog.info(e.toString());
        return false;
    }
    return true;
}

/**
 * 對某個機器傳送訊息
 *
 * @param message
 * @param vmcNo   機器編號
 * @return true, 返回傳送的訊息, false,返回failed字串
 */
public static String sendMessage(String message, long vmcNo) {
    boolean success = false;
    for (WebSocketServer server : sWebSocketServers) {
        if (server.mVmcNo == vmcNo) {
            success = server.sendMessage(message);
            break;
        }
    }
    return success ? message : "failed";
}

}

5,配置外部訪問推送地址介面控制器

package com.gsc.websocket.demo;

import com.google.gson.Gson;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WebSocketController {
//推送到某個裝置的資訊
@RequestMapping(value = “/operation/{vmc}/{cmd}”)
public String remote(@PathVariable(“vmc”) long vmc, @PathVariable(“cmd”) String cmd){
System.out.print(“remote”);
RemoteOperation operation = new RemoteOperation();
operation.setVmc_no(vmc);
operation.setOperation(cmd);
String message = new Gson().toJson(operation);
System.out.println(“message in json is :”+message);
return WebSocketServer.sendMessage(message,vmc);
}
@RequestMapping(value = “/test”)
public String test(){
System.out.print(“test”);
return “hello world”;
}
}

#6 以上完成後端的程式碼下面直接看Android程式碼 註明(沒啥技術含量)

package com.example.administrator.myapplication;
import android.os.Bundle;
import android.os.Looper;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.net.URISyntaxException;

/**

  • Created by Administrator on 2018/11/17.
    */
    public class webSocketDemo extends AppCompatActivity {
    private WebSocketClient webSocketClient;
    private String TAG=“gsc”;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.testwebsocket);
    }
    public void test(View view) {
    try {
    webSocketClient=new WebSocketClient(new URI(“ws://192.168.1.100:8080/websocket/1089”)) {
    @Override
    public void onOpen(ServerHandshake handshakedata) {
    Log.d(TAG, “onOpen:”);
    new Thread(){
    @Override
    public void run() {
    super.run();
    while (true){
    SystemClock.sleep(2000);

                             try {
                                 webSocketClient.send("哈哈");
                             }catch (Exception e){
                                 webSocketClient.reconnect();
                             }
                         }
    
                     }
                 }.start();
             }
             @Override
             public void onMessage(String message) {
                 Log.d(TAG, "message:"+message);
                 Looper.prepare();
                 Toast.makeText(getApplicationContext(),"收到訊息:"+message,1).show();
                 Looper.loop();
             }
    
             @Override
             public void onClose(int code, String reason, boolean remote) {
                 Log.d(TAG, "onClose:"+remote);
             }
    
             @Override
             public void onError(Exception ex) {
                 Log.d(TAG, "onError:"+ex.getMessage());
             }
         };
     } catch (URISyntaxException e) {
         e.printStackTrace();
     }
     webSocketClient.connect();
    

    }
    }

最後附上原始碼