当前位置:网站首页>websocket

websocket

2022-04-23 16:50:00 Kramer_ one hundred and forty-nine

Reference cases

Concept

websocket It's a full duplex channel , After establishing the connection, you can send messages in both directions .

Tomcat 7.0.5 After that, I started to support websocket, And implemented websocket standard .Java websocket The application consists of a series of WebSocketEndpoint form . One Endpoint It's a Java object , representative WebSocket End of link , For the server , It can be regarded as dealing with WebSocket Message interface , It's like servlet Handle http equally .( notes : Build a websocket The link will create a new Endpoint object )

There are two ways to define Endpointt:
1、 Inherit javax.websocket.Endpoint Class and implement its methods .
2、 Definition POJO And add @ServerEndpoint annotation

The data transfer

The server accepts data

adopt Session( and http Medium session Different ) add to MessageHandler Message processor to receive messages , When defining by annotation Endpoint when , adopt @OnMessage The annotation specifies the method of accepting the message .

The server pushes data

The message is sent by RemoteEndpoint complete , In fact, it is by Session maintain , According to usage , We can go through Session.getBasicRemote Get synchronization message sending instance , And then call sendXxx() Method can send a message , Can pass Session.getAsyncRemote Get asynchronous message sending instance .

The backend implementation

Inherit Endpoint Realization way

onOpen Method : Automatically call... After the link is established
onClose Method : Link close auto call
onError Method : If there is a problem in the link, automatically call

annotation @ServerEndpoint Realization way ( The main )

@OnClose
@OnOpen
@OnError

Sample code

@ServerEndpoint("/robin")// Followed by the resource path 
public class ChatEndPoint{
    
	private static Set<ChatEndPoint> webSocketSet = new HashSet<>();

	private Session session;
	
	@OnMessage
	public void onMessage(String message,Session session)throws IOException{
    
		//message  Is the message sent by the received client ;session
		System.out.println("get message"+message);
		System.out.println(session);
		// Send messages to other users 
		for(ChatEndPoint chat:webSocketSet){
    
			if(chat!=this){
    
				chat.session.getBasicRemote().setText(message);
			}
		}
	}
	
	@OnOpen
	public void onOpen(Session session){
    
		this.session = session;
		webSocketSet.add(this);
	}
	
	@OnClose
	public void onClose(Session session){
    
		
	}

	@OnError
	public void onError(Session session,Throwable error){
    
		
	}
}

be based on websocket Realize chat room ( Back end code )

rely on

webSocket rely on

<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

public resource

Message class , client to Server side

@Data
public class Message{
    
	private String toName;
	private String message;
}

ResultMessage, Server side to client

@Data
public class ResultMessage{
    
	private boolean isSystem;
	private String fromName;
	private Object message;// If it is a system message, it is an array 
}

MessageUtils, Message tool class

public class MessageUtils {
    
    public static String getMessage(boolean isSystemMessage,String fromName,Object message){
    
        try {
    
            ResultMessage result = new ResultMessage();
            result.setSystem(isSystemMessage);
            result.setMessage(message);
            if (fromName!=null){
    
                result.setFromName(fromName);
            }
            // Convert a string to json Format string 
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(result);
        }catch (JsonProcessingException e){
    
            e.printStackTrace();
        }
        return null;
    }
}

The user login

@RestController
public class LoginController {
    
    @RequestMapping("/toLogin")
    public Result tologin(@RequestParam("user") String user,@RequestParam("pwd") String pwd, HttpSession session){
    
        Result result = new Result();
        if (user.equals(" Zhang San ")&&pwd.equals("123")){
    
            result.setFlag(true);
            session.setAttribute("user",user);
        }else if (user.equals(" Li Si ")&&pwd.equals("123")){
    
            result.setFlag(true);
            session.setAttribute("user",user);
        }else if (user.equals("123")&&pwd.equals("123")){
    
            result.setFlag(true);
            session.setAttribute("user",user);
        }
        else if (user.equals(" Wang Wu ")&&pwd.equals("123")){
    
            result.setFlag(true);
            session.setAttribute("user",user);
        }else {
    
            result.setFlag(false);
            result.setMessage(" Login failed ");
        }
        return result;
    }

    @RequestMapping("/getUsername")
    public String getUsername(HttpSession session){
    
        String username = (String) session.getAttribute("user");
        return username;
    }
}

Endpoint

@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfigurator.class)// Note that there 
@Component
public class ChatEndpoint {
    

    // Used to store each user's client object ChatEndpoint object 
    private static Map<String,ChatEndpoint> onlineUsers = new ConcurrentHashMap<>();

    // Statement session object , Through the object, you can send a message to the specified user 
    private Session session;

    // Statement HttpSession object , We were HttpSession The user name... Is stored in the object 
    private HttpSession httpSession;

    // Connection is established 
    @OnOpen
    public void onOpen(Session session, EndpointConfig config){
    
        this.session = session;
        HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        this.httpSession = httpSession;
        // Store the login object 
        String username = (String)httpSession.getAttribute("user");
        onlineUsers.put(username,this);

        // Push the user name of the current online user to all clients 
        //1  Get message 
        String message = MessageUtils.getMessage(true, null, getNames());
        //2  Call methods to push system messages 
        broadcastAllUsers(message);
    }

    private void broadcastAllUsers(String message){
    
        try {
    
            // Push messages to all clients 
            Set<String> names = onlineUsers.keySet();
            for (String name : names) {
    
                ChatEndpoint chatEndpoint = onlineUsers.get(name);
                chatEndpoint.session.getBasicRemote().sendText(message);
            }
        }catch (Exception e){
    
            e.printStackTrace();
        }
    }

    // Return online user name 
    private Set<String> getNames(){
    
        return onlineUsers.keySet();
    }

    // Received a message 
    @OnMessage
    public void onMessage(String message,Session session){
    
        // Convert data into objects 
        try {
    
            ObjectMapper mapper =new ObjectMapper();
            Message mess = mapper.readValue(message, Message.class);
            String toName = mess.getToName();
            String data = mess.getMessage();
            String username = (String) httpSession.getAttribute("user");
            String resultMessage = MessageUtils.getMessage(false, username, data);
            // send data 
            onlineUsers.get(toName).session.getBasicRemote().sendText(resultMessage);
        } catch (Exception e) {
    
            e.printStackTrace();
        }

    }
    // close 
    @OnClose
    public void onClose(Session session) {
    
        String username = (String) httpSession.getAttribute("user");
        // Delete the specified user from the container 
        onlineUsers.remove(username);
        MessageUtils.getMessage(true,null,getNames());
    }
}

Configuration class

You need to add a configuration class Spring Will manage .

@Configuration
public class WebSocketConfig {
    
    @Bean
    // Inject ServerEndpointExporter bean object , Automatically register using annotations @ServerEndpoint Of bean
    public ServerEndpointExporter serverEndpointExporter(){
    
        return new ServerEndpointExporter();
    }
}

other

obtain HttpSession Class

public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator {
    
    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
    
        // obtain HttpSession object 
        HttpSession httpSession = (HttpSession) request.getHttpSession();
        sec.getUserProperties().put(HttpSession.class.getName(),httpSession);
    }
}

版权声明
本文为[Kramer_ one hundred and forty-nine]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231359460626.html