java 後端實現WebSocket學習篇和客戶端Android 通訊
1.建立SpringBoot Java web 專案這裡當你已經熟悉Springboot
2,引入需要的WebSocket maven依賴
org.springframework.boot spring-boot-starter-websocket 3.配置webSocketpackage 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();
}
}
最後附上原始碼