最近有个项目需要实现视频流的信息交换处理,但是之前一直都没有写过有关的代码,所以就想到了websocket接口。
java创建一个socket非常简单,繁琐的可能是日常的业务信息处理,下面看下一段代码:
import model.User;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* Created by alan.luo on 2017/9/10.
*/
@ServerEndpoint(value = "/websocket2")
public class TestWebSocket {
@OnOpen
public void onOpen(Session session, EndpointConfig endpointConfig) {
sendMsg(session,"Welcome back.");
//push list.
User user = new User();
user.setId(Integer.parseInt(session.getId()));
Map<String,List<String>> map = session.getRequestParameterMap();
user.setUserName(map.get("userName").get(0));
user.setSession(session);
//has client come in,so server must be save the session to the application.class.
Application.getInstance().putSession(user);
}
@OnMessage
public void onMessage(Session session,String message){
System.out.println("++++++++++:"+message);
//if has user push message to the server.then server will each all the client and send message too.
for (User user:Application.getInstance().getUsers()){
sendMsg(user.getSession(),user.getUserName() + " say:"+message);
}
}
@OnClose
public void onClose(Session session, CloseReason closeReason){
List<User> list = Application.getInstance().getUsers();
//pop list.
for (int i = 0;i<list.size();i++){
if (Integer.parseInt(session.getId()) == list.get(i).getId()){
list.remove(i);
Application.getInstance().setUsers(list);
break;
}
}
}
@OnError
public void onError(Session session, Throwable thr) {
System.out.println("+++++++++onError"+thr.getMessage());
}
/**
* send message to session.
* @param session
* @param message
*/
protected void sendMsg(Session session,String message){
System.out.println(message);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
session.getBasicRemote().sendText(message+" >"+sdf.format(new Date()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
当有客户端进入,则把客户端保存到application这个实例中,application是自定义的一个类,实现了单例,所以保存进去是最合适的,当有消息进入时,server将从application读取session list 并且遍历全部session and send the message。
Application实例的代码:
import model.User;
import java.util.ArrayList;
import java.util.List;
/**
* Created by alan.luo on 2017/9/10.
*/
public class Application {
private List<User> users;
private static Application app;
public Application(){
users = new ArrayList<>();
}
public static Application getInstance(){
if (app == null){
app = new Application();
}
return app;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public void putSession(User s){
this.users.add(s);
}
}
User实体类的代码:
package model;
import javax.websocket.Session;
/**
* Created by alan.luo on 2017/9/6.
*/
public class User {
private int id;
private String userName;
private String userPassword;
private Session session;
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPasswd) {
this.userPassword = userPasswd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", userPassword='" + userPassword + '\'' +
'}';
}
}
可能会有错误,那是因为需要配置一下web.xml
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/websocket2</url-pattern>
</servlet-mapping>
剩下的就是javascript客户端的代码了:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<p><input type="text" id="userName" value="" placeholder="输入名字进入聊天室"></p>
</div>
<div>
<textarea rows="16" cols="40" id="content"></textarea>
</div>
<div>
<input type="text" id="message" value="" placeholder="输入内容"/>
<button type="button" id="send">send</button>
</div>
<div>
<button type="button" id="connect">connect</button>
<button type="button" id="destroy">destroy</button>
</div>
<script>
var connect = document.getElementById("connect");
var content = document.getElementById("content");
var message = document.getElementById("message");
var destroy = document.getElementById("destroy");
var send = document.getElementById("send");
var userName = document.getElementById("userName");
var socket = null;
connect.addEventListener("click",function () {
console.log("connect")
if(userName.value.length <= 2){
return false;
}
socket = new WebSocket("ws://localhost:8080/websocket2?userName="+userName.value);
socket.onopen = function (p1) {
console.log("onopen",p1)
}
socket.onclose = function (p1) {
console.log("onclose",p1)
}
socket.onerror = function (p1) {
console.log("onerror",p1)
}
socket.onmessage = function (p1) {
console.log("onmessage",p1)
content.innerHTML = (content.innerHTML + p1.data + "\n")
}
});
destroy.addEventListener("click",function () {
console.log("destroy")
socket.close();
});
send.addEventListener("click",function () {
console.log("send")
socket.send(message.value);
message.value = "";
});
</script>
</body>
</html>
最后上传一张效果图吧:
近期评论