本文是基于注释的案例,对于发送语音采用了类似文件上传下载一样的方式实现,不过播放会有一点儿延迟,正在改进。
1、首先导入webScoket相关的jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、开启WebScoket支持
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 {
/**
*外置tomcat不需要配置此bean
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3、定义一个websocket服务器端
/**
* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
* 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
*/
@ServerEndpoint(value = "/{room}/{Id}")
@Component
public class MyWebSocket {
/**
* 自增或自减,若没有进行额外的同步操作,在多线程环境下就是线程不安全的
*/
private static AtomicInteger room1OnlineCount = new AtomicInteger(0);
private static AtomicInteger room2OnlineCount = new AtomicInteger(0);
private static AtomicInteger room3OnlineCount = new AtomicInteger(0);
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
*/
/* private static CopyOnWriteArraySet<MyWebSocket> room1WebSocketSet = new CopyOnWriteArraySet<>();
private static CopyOnWriteArraySet<MyWebSocket> room2WebSocketSet = new CopyOnWriteArraySet<>();
private static CopyOnWriteArraySet<MyWebSocket> room3WebSocketSet = new CopyOnWriteArraySet<>();
*/
/**
* 所有的MyWebSocket对象放在一个map中,方便私聊直接发送
*/
private static ConcurrentHashMap<String, MyWebSocket> roomMap = new ConcurrentHashMap<>(10000);
/**
* 每个聊天室一个map方便群发信息
*/
private static ConcurrentHashMap<String, MyWebSocket> room1Map = new ConcurrentHashMap<>(10000);
private static ConcurrentHashMap<String, MyWebSocket> room2Map = new ConcurrentHashMap<>(10000);
private static ConcurrentHashMap<String, MyWebSocket> room3Map = new ConcurrentHashMap<>(10000);
/**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
private Session session;
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("Id") String Id, @PathParam("room") String room) {
this.session = session;
//在线人数++
room1OnlineCount.incrementAndGet();
roomMap.put(Id,this);
System.out.println(this.session.getId());
String substring = room.substring(room.length() - 1);
if (Integer.parseInt(substring) == 1) {
//session加入room1
// room1WebSocketSet.add(this);
room1Map.put(Id,this);
//在线人数++
room1OnlineCount.incrementAndGet();
} else if (Integer.parseInt(substring) == 2) {
//session加入room2
// room2WebSocketSet.add(this);
room2Map.put(Id,this);
//在线人数++
room2OnlineCount.incrementAndGet();
} else {
//session加入room3
// room3WebSocketSet.add(this);
room3Map.put(Id,this);
//在线人数++
room3OnlineCount.incrementAndGet();
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose( @PathParam("Id")String userId, @PathParam("room")String room) {
//room1WebSocketSet.remove(this);
room1OnlineCount.decrementAndGet();
String substring = room.substring(room.length() - 1);
if (Integer.parseInt(substring)==1){
// room1WebSocketSet.remove(this);
room1Map.remove(userId);
room1OnlineCount.decrementAndGet();
}else if (Integer.parseInt(substring)==2){
// room2WebSocketSet.remove(this);
room2OnlineCount.decrementAndGet();
room2Map.remove(userId);
}else{
// room3WebSocketSet.remove(this);
room3OnlineCount.decrementAndGet();
room3Map.remove(userId);
}
System.out.println("有一连接关闭!当前在线人数为" + room1OnlineCount);
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
* */
@OnMessage
public void onMessage(String message,@PathParam("room")String room) {
System.out.println(message);
//客户端定时ping一下,如果不同就直接重新建立连接
/*if (message.equals("ping")){
try {
this.session.getBasicRemote().sendText("pong");
} catch (IOException e) {
System.out.println("IO 异常");
e.printStackTrace();
}
}*/
String KEY_PRE = "All";
JSONObject jsonObject = JSON.parseObject(message);
String to = jsonObject.getString("to");
String substring = room.substring(room.length() - 1);
if(KEY_PRE.equals(to)){
sendMessageToAll(message,substring);
}else{
sendMessage(message, to);
}
}
/**
* 发生错误时调用
* @param error
*/
@OnError
public synchronized void onError(Throwable error) {
System.out.println("发生错误");
error.printStackTrace();
}
/**
* 私聊
* @param message
*/
public void sendMessage(String message,String Id){
//判断链接是否正常
try {
//根据ID查到接收方的session发送信息
roomMap.get(Id).session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 群发
* @param message
* @param room
*/
public void sendMessageToAll(String message,String room){
// if(this.session.isOpen()){
System.out.println(message);
try {
if(room.equals("1")){
for(String key : room1Map.keySet()){
room1Map.get(key).session.getBasicRemote().sendText(message);
}
}
if(room.equals("2")){
for(String key : room2Map.keySet()){
room2Map.get(key).session.getBasicRemote().sendText(message);
}
}
if(room.equals("3")){
for(String key : room3Map.keySet()){
room3Map.get(key).session.getBasicRemote().sendText(message);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
//}
}
4、发送语音的controller
/**
* 发送语音和上传文件
*/
@RestController
@RequestMapping("/api")
public class FileWebScoket {
/**
* 录音图片上传
* @param request
* @param file
* @param room
*/
@RequestMapping(path = { "websocket-file" }, method = { RequestMethod.POST })
public void fileUpload(HttpServletRequest request, @RequestParam("file") MultipartFile file,String room,String type,String userName,String userImg,String id,String to) {
// 判断文件是否为空
String str ="/public/"+System.currentTimeMillis()+file.getOriginalFilename();
String filePath=request.getServletContext().getRealPath("/")+"/WEB-INF"+str;
if (!file.isEmpty()) {
try {
// 文件保存路径
file.transferTo(new File(filePath));
MyWebSocket webSocket=new MyWebSocket();
webSocket.sendMessageToAll("{\"type\":" +type+
",\"userName\":\"" +userName+
"\",\"userImg\":\"" +userImg+
"\",\"audio\":\""+
str+"\",\"id\":" +id+
",\"content\":\"1111\",\"to\":\"" +to+
"\"}", room);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/* @RequestMapping(path = { "websocket-file-1" }, method = { RequestMethod.POST })
public void importAudio(HttpServletRequest request,@RequestParam("file") String file) {
file = file.replaceAll("data:audio/mp3;base64,","");
byte[] audioByte=Base64.decodeBase64(file);
String fileName= KeyUtil.genUniqueKey()+".mp3";
String filePath=request.getServletContext().getRealPath("/")+"/WEB-INF/public/";
try {
FileUtil.uploadFile(audioByte, filePath, fileName);
MyWebSocket webSocket=new MyWebSocket();
webSocket.sendMessageToAll("", "1");
}catch (Exception e){
e.printStackTrace();
}
}*/
}
到此已经基本实现了基本功能。
接下来试试使用buffer直接推送语音,这样可能发送语音不会有延迟的现象,语音直接保存在客户端,直接点击播放。
1万+



被折叠的 条评论
为什么被折叠?



