后端原理不是很复杂 每次用户连接到服务端的时候会携带一个username,连接成功之后后端把username和当前soket添加到Map中
webSocketMap. put ( username, this ) ;
需要给指定用户发送消息的时候就通过username获取WebSoketServer通过.getBasicRemote().sendText()向用户发送消息
for ( Map. Entry < String , SongWebSoketServer > server : webSocketMap. entrySet ( ) ) {
if ( server. getKey ( ) . equals ( "接收消息的用户名" ) ) {
server. getValue ( ) . session. getBasicRemote ( ) . sendText ( "想要发送的消息" ) ;
}
}
需要发送复杂消息的情况下可以New一个JSON对象
JSONObject jsonObject = new JSONObject ( ) ;
jsonObject. put ( "code" , 200 ) ;
jsonObject. put ( "message" , message) ;
jsonObject. toJSONString ( ) ;
完整代码:
前端页面中比较简单
< template>
< el- input v- model= "content" / >
< el- button @click= "send" > 发送< / el- button>
< / template>
< script>
export default {
data ( ) {
return {
socket : "" ,
content : '' ,
}
} ,
created ( ) {
this . init ( ) ;
} ,
methods : {
init : function ( ) {
if ( typeof ( WebSocket) === "undefined" ) {
alert ( "您的浏览器不支持socket" ) ;
} else {
this . socket = new WebSocket ( "ws://localhost:8080/websocket/" + "username" ) ;
this . socket. onopen = this . open;
this . socket. onerror = this . error;
this . socket. onmessage = this . getMessage;
}
} ,
open : function ( ) {
console. log ( "socket连接成功" ) ;
} ,
error : function ( ) {
console. log ( "连接错误" ) ;
} ,
getMessage : function ( msg ) {
console. log ( msg)
} ,
send : function ( ) {
this . socket. send ( this . content) ;
this . content = "" ;
} ,
close : function ( ) {
console. log ( "socket已经关闭" ) ;
}
} ,
destroyed ( ) {
this . socket. onclose = this . close;
}
}
< / script>
< style lang= "scss" scoped>
< / style>
SpirngBoot项目中创建WebSoket模块
pom中引入
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-websocket</ artifactId>
</ dependency>
新建WebSoketServer
import com. alibaba. fastjson. JSONObject ;
import com. ruoyi. common. utils. StringUtils ;
import org. slf4j. Logger ;
import org. slf4j. LoggerFactory ;
import org. springframework. stereotype. Component ;
import org. springframework. stereotype. Service ;
import javax. websocket. * ;
import javax. websocket. server. PathParam ;
import javax. websocket. server. ServerEndpoint ;
import java. io. IOException ;
import java. util. HashMap ;
import java. util. Map ;
import java. util. concurrent. ConcurrentHashMap ;
@Component
@Service
@ServerEndpoint ( value = "/websocket/{username}" )
public class WebSoketServer {
static final Logger loggger = LoggerFactory . getLogger ( WebSoketServer . class ) ;
private static ConcurrentHashMap < String , WebSoketServer > webSocketMap = new ConcurrentHashMap < > ( ) ;
private Session session;
private String username = "" ;
@OnOpen
public void onOpen ( Session session, @PathParam ( "username" ) String username) throws IOException {
this . session = session;
this . username = username;
if ( webSocketMap. containsKey ( username) ) {
webSocketMap. remove ( username) ;
webSocketMap. put ( username, this ) ;
} else {
webSocketMap. put ( username, this ) ;
}
loggger. info ( "用户:" + username + "连接:当前在线人数为:" + webSocketMap. size ( ) ) ;
}
@OnClose
public void onClose ( ) {
if ( webSocketMap. containsKey ( username) ) {
webSocketMap. remove ( username) ;
}
loggger. info ( "用户" + username + "退出:当前在线人数为:" + webSocketMap. size ( ) ) ;
}
@OnMessage
public void onMessage ( String message, Session session) {
loggger. info ( "用户" + username + "消息:内容:" + message) ;
}
public static void sendInfo ( String message, String username) {
loggger. info ( "发送消息到:" + username + ",内容:" + message) ;
if ( StringUtils . isNotBlank ( username) && webSocketMap. containsKey ( username) ) {
try {
webSocketMap. get ( username) . sendMessage ( message) ;
} catch ( Exception e) {
loggger. error ( e. getMessage ( ) , e) ;
}
} else {
loggger. error ( "用户" + username + ",不在线!" ) ;
}
}
@OnError
public void onError ( Session session, Throwable error) {
loggger. error ( "用户" + username + "错误:原因:" + error. getMessage ( ) ) ;
error. printStackTrace ( ) ;
}
public void sendMessage ( String message) throws IOException {
this . session. getBasicRemote ( ) . sendText ( message) ;
}
}