设计思路
使用websocket通信,客户端采用C#开发界面,服务端使用Java开发,最终实现Java服务端向C#客户端发送消息和文件,C#客户端实现语音广播的功能。
Java服务端设计
1package servlet.websocket; 2 3import java.io.IOException; 4import java.util.Map; 5import java.util.concurrent.ConcurrentHashMap; 6import javax.websocket.OnClose; 7import javax.websocket.OnError; 8import javax.websocket.OnMessage; 9import javax.websocket.OnOpen; 10import javax.websocket.Session; 11import javax.websocket.server.PathParam; 12import javax.websocket.server.ServerEndpoint; 13 14import servlet.Log; 15 16/** 17 * websocket服务端 18 * 19 * @author leibf 20 * 21 */ 22@ServerEndpoint(value = "/websocket/{clientId}") 23public class WebSocketServer { 24 private final Log log = new Log(WebSocketServer.class); 25 private Session session; 26 private String clientId; 27 private static Map<String, WebSocketServer> clients = new ConcurrentHashMap<String, WebSocketServer>(); 28 29 // 连接时执行 30 @OnOpen 31 public void onOpen(@PathParam("clientId") String clientId, Session session) throws IOException { 32 this.session = session; 33 this.clientId = clientId; 34 clients.put(clientId, this); 35 log.info("新连接:" + clientId); 36 } 37 38 // 关闭时执行 39 @OnClose 40 public void onClose(@PathParam("clientId") String clientId, Session session) { 41 clients.remove(clientId); 42 43 log.info("连接 " + clientId + " 关闭"); 44 } 45 46 // 收到消息时执行 47 @OnMessage 48 public void onMessage(String message, Session session) throws IOException { 49 log.info("收到用户的消息: "+ message); 50 /*if("getMpDefsAndRtDatas".equals(message)){ 51 String msg = UnityServlet.getInstance().getAllMpDefsAndRtDatas(); 52 this.sendMessage(session, msg); 53 }*/ 54 } 55 56 // 连接错误时执行 57 @OnError 58 public void onError(@PathParam("clientId") String clientId, Throwable error, Session session) { 59 log.info("用户id为:" + clientId + "的连接发送错误"); 60 error.printStackTrace(); 61 } 62 63 /** 64 * 发送消息给某个客户端 65 * @param message 66 * @param To 67 * @throws IOException 68 */ 69 public static void sendMessageTo(String message, String To) throws IOException { 70 for (WebSocketServer item : clients.values()) { 71 if (item.clientId.equals(To)) 72 item.session.getAsyncRemote().sendText(message); 73 } 74 } 75 76 /** 77 * 发送消息给某些客户端 78 * @param message 79 * @param To 80 * @throws IOException 81 */ 82 public static void sendMessageToSomeone(String message, String To) throws IOException { 83 for (WebSocketServer item : clients.values()) { 84 if (item.clientId.startsWith(To)) 85 item.session.getAsyncRemote().sendText(message); 86 } 87 } 88 89 /** 90 * 发送消息给所有客户端 91 * @param message 92 * @throws IOException 93 */ 94 public static void sendMessageAll(String message) throws IOException { 95 for (WebSocketServer item : clients.values()) { 96 item.session.getAsyncRemote().sendText(message); 97 } 98 } 99 100 /** 101 * 发送消息 102 * @param session 103 * @param message 104 * @throws IOException 105 */ 106 private void sendMessage(Session session,String message) throws IOException{ 107 session.getBasicRemote().sendText(message); 108 } 109}
Java端发送请求指令
1String clientId = "broadcast"; 2try { 3 WebSocketServer.sendMessageTo("broadcast",clientId); 4} catch (IOException e) { 5 e.printStackTrace(); 6}
C#客户端设计
websocket连接
1WebSocket websocket = null; 2private void websocket_MessageReceived(object sender, MessageReceivedEventArgs e){ 3 //接收服务端发来的消息 4 MessageReceivedEventArgs responseMsg = (MessageReceivedEventArgs)e; 5 string strMsg = responseMsg.Message; 6 if(strMsg.Equals("broadcast")){ 7 websocketToPlay(); 8 }else if(strMsg.Equals("broadcastStop")){ 9 websocketToStop(sender,e); 10 } 11} 12 13private void websocket_Closed(object sender, EventArgs e){ 14 DisplayStatusInfo("websocket connect failed!"); 15} 16 17private void websocket_Opened(object sender, EventArgs e){ 18 DisplayStatusInfo("websocket connect success!"); 19} 20 21//websocket连接 22private void connectWebsocket(){ 23 websocket = new WebSocket("ws://localhost:8080/FrameServlet/websocket/broadcast"); 24 websocket.Opened += websocket_Opened; 25 websocket.Closed += websocket_Closed; 26 websocket.MessageReceived += websocket_MessageReceived; 27 websocket.Open(); 28}
跨线程操作控件 --- InvokeRequired属性与Invoke方法
1private delegate void DoLog(string msg); 2private void DisplayStatusInfo(string msg) 3{ 4 if (this.InvokeRequired) 5 { 6 DoLog doLog = new DoLog(DisplayStatusInfo); 7 this.Invoke(doLog, new object[] { msg }); 8 }else{ 9 if (msg.Trim().Length > 0) 10 { 11 ListBoxStatus.Items.Insert(0, msg); 12 if (ListBoxStatus.Items.Count > 100) 13 { 14 ListBoxStatus.Items.RemoveAt(ListBoxStatus.Items.Count - 1); 15 } 16 } 17 } 18}