使用 SSM 框架设计用户登录,用户登录后,可以监测查看其他哪些用户在线,重点 演示当其他用户下线(包括登录超时、关闭浏览器、退出登录操作等),该用户自动从在线 列表中消失完整代码
时间: 2024-05-05 19:17:19 浏览: 58
由于SSM框架包含Spring、SpringMVC和MyBatis,本题的实现主要是在SpringMVC中进行。
首先,需要在SpringMVC配置文件中添加WebSocket配置:
```xml
<!-- 开启WebSocket支持 -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 配置WebSocket处理器 -->
<bean id="webSocketHandler" class="com.example.WebSocketHandler"/>
<bean class="org.springframework.web.socket.server.standard.ServerEndpointExporter"/>
```
其中,`com.example.WebSocketHandler`是我们自己编写的WebSocket处理器,后面会给出具体实现。
然后,在SpringMVC中编写控制器处理用户登录、获取在线用户列表和用户退出登录操作:
```java
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/login")
@ResponseBody
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
HttpSession session) {
User user = userService.login(username, password);
if (user != null) {
session.setAttribute("user", user);
return "success";
} else {
return "fail";
}
}
@RequestMapping("/online")
@ResponseBody
public List<String> onlineUsers() {
return WebSocketHandler.getOnlineUsers();
}
@RequestMapping("/logout")
public String logout(HttpSession session) {
session.removeAttribute("user");
return "redirect:/login.html";
}
}
```
其中,`userService`是我们自己编写的用户服务类,用于处理用户登录操作。`WebSocketHandler.getOnlineUsers()`是静态方法,用于获取当前在线用户列表。
最后,是`com.example.WebSocketHandler`的具体实现:
```java
@Component
@ServerEndpoint("/websocket/{username}")
public class WebSocketHandler {
private static final Map<String, Session> sessions = new ConcurrentHashMap<>();
private static final Map<String, String> usernames = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(@PathParam("username") String username, Session session) {
sessions.put(session.getId(), session);
usernames.put(session.getId(), username);
broadcast(username + "上线了");
}
@OnClose
public void onClose(Session session) {
String username = usernames.get(session.getId());
sessions.remove(session.getId());
usernames.remove(session.getId());
broadcast(username + "下线了");
}
private void broadcast(String message) {
for (Session session : sessions.values()) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static List<String> getOnlineUsers() {
List<String> onlineUsers = new ArrayList<>();
for (String username : usernames.values()) {
onlineUsers.add(username);
}
return onlineUsers;
}
}
```
`WebSocketHandler`实现了WebSocket处理器的接口,并使用`@ServerEndpoint`注解标注了WebSocket的请求URL。`sessions`和`usernames`分别记录了所有会话和会话对应的用户名。`onOpen`方法在有新的WebSocket连接时被调用,将新的会话和用户名加入到对应的Map中,并向所有在线用户广播该用户上线的消息。`onClose`方法在WebSocket连接关闭时被调用,将该会话和用户名从对应的Map中移除,并向所有在线用户广播该用户下线的消息。`broadcast`方法用于向所有在线用户广播消息。`getOnlineUsers`方法是静态方法,用于从`usernames`中获取所有在线用户的用户名列表。
需要注意的是,在`onClose`方法中,需要将该会话和用户名从对应的Map中移除,以避免内存泄漏。此外,在实际应用中,还需要考虑用户登录超时、关闭浏览器等情况,通过定时清理无效会话可以避免服务器资源被无效会话占用。
阅读全文