如何创建可从其他 类 访问的 Websocket SessionManager
How to create a Websocket SessionManager that are reachable from other classes
我正在开发一个带有 WebSocket 的应用程序,我想将客户端 ID 和会话保存到管理器中,但是当我还希望能够从另一个服务器访问它时,我很难理解如何正确地做到这一点 class 自动装配。
public class Client {
private String id;
private Session session;
private MessageHandler handler;
Client(String id, Session session, MessageHandler handler) {
this.id = id;
this.session = session;
this.handler = handler;
}
}
public class ClientsManager {
private Set<Client> clientSet = new CopyOnWriteArraySet<>();
public Set<Client> getClients() {
return this.clientSet;
}
public void addClient(Client client) {
this.clientSet.add(client);
}
public void removeClient(Client client) {
clientSet.remove(client);
}
}
public class WebsocketServerEndpoint {
public static final ClientsManager manageClients = new ClientsManager();
@OnOpen
public void onOpen(Session session, @PathParam("connectId") String connectId) throws IOException, EncodeException {
MessageHandler messageHandler = new MessageHandler();
Client client = new Client(connectId, session, messageHandler);
this.client = client;
manageClients.addClient(client);
}
....
....
....
....
}
来自另一个 class:
public class DoSomething {
@Autowired
WebsocketServerEndpoint serverEndpoint;
public String doSomething() {
int numberOfClients = serverEndpoint.getClients().size()
return numberOfClients;
}
}
据我了解。这是不正确的,你不应该自动装配静态字段等等。
我可以在我的 DoSomething class 中调试 serverEndpoint: null 时看到,但如果我有一个连接的客户端,我会得到 1 个连接的客户端,依此类推。
当我这样做时,我将在 DoSomething class 中获得正确数量的客户。
我只是误解了这个并且它像我一样工作吗?
或者我应该怎么做?
他们是编写我的 Client 和 ClientsManager classes 的更好方法吗?
据我所知,如果无论如何我都想“自动装配”,有两种可能的方法。
- 对静态字段使用构造函数@Autowired
- 使用@PostConstruct 将值设置为静态字段
但是,当我想实例化“public static final ClientsManager manageClients = new ClientsManager();”
时,这是如何工作的?
抱歉我的愚蠢问题,但我觉得我不完全理解这一点。
如果您想了解有关此主题的更多信息,请搜索 Spring 依赖注入,但我会写一个简短的摘要。
为了能够@Autowire 组件,您必须创建一个@Bean 或@Service 或@Component。
创建beand首先创建一个Configurationclass,然后在里面创建一个Beand或Beans
@Configuration
public class Configuration {
@Value("${configuration.property.name}")
String username;
@Bean
public WebsocketServerEndpoint ebsocketServerEndpoint () {
return new WebsocketServerEndpoint();
}
}
@Value
不是必需的,只需提及此注释,您就可以从 spring application.properties
文件中获得 属性 名称。
此时您已经创建了 class 的 @Bean 实例,它被注册为单例 class。您可以从应用程序中的任何位置获取此一份副本 class,只需自动装配它即可。
或者基于用户构造器的依赖注入。 (@Autowired 不是首选)。
不要创建 bean,只需将 @Component
注释添加到您想要 Autowire
的 class,但我显示了构造函数注入。
@Component
public class WebsocketServerEndpoint {
public String test(){
return "test";
}
}
@RestController
public class DoSomething {
private final WebsocketServerEndpoint websocketHandler;
public DoSomething(WebsocketServerEndpoint websocketHandler) {
this.websocketHandler = websocketHandler;
}
@GetMapping(value = "/test")
public String test() {
return websocketHandler.test();
}
}
您甚至可以使用 curl GET 请求测试此端点。 curl http://localhost:8080/test
我正在开发一个带有 WebSocket 的应用程序,我想将客户端 ID 和会话保存到管理器中,但是当我还希望能够从另一个服务器访问它时,我很难理解如何正确地做到这一点 class 自动装配。
public class Client {
private String id;
private Session session;
private MessageHandler handler;
Client(String id, Session session, MessageHandler handler) {
this.id = id;
this.session = session;
this.handler = handler;
}
}
public class ClientsManager {
private Set<Client> clientSet = new CopyOnWriteArraySet<>();
public Set<Client> getClients() {
return this.clientSet;
}
public void addClient(Client client) {
this.clientSet.add(client);
}
public void removeClient(Client client) {
clientSet.remove(client);
}
}
public class WebsocketServerEndpoint {
public static final ClientsManager manageClients = new ClientsManager();
@OnOpen
public void onOpen(Session session, @PathParam("connectId") String connectId) throws IOException, EncodeException {
MessageHandler messageHandler = new MessageHandler();
Client client = new Client(connectId, session, messageHandler);
this.client = client;
manageClients.addClient(client);
}
....
....
....
....
}
来自另一个 class:
public class DoSomething {
@Autowired
WebsocketServerEndpoint serverEndpoint;
public String doSomething() {
int numberOfClients = serverEndpoint.getClients().size()
return numberOfClients;
}
}
据我了解。这是不正确的,你不应该自动装配静态字段等等。
我可以在我的 DoSomething class 中调试 serverEndpoint: null 时看到,但如果我有一个连接的客户端,我会得到 1 个连接的客户端,依此类推。 当我这样做时,我将在 DoSomething class 中获得正确数量的客户。 我只是误解了这个并且它像我一样工作吗? 或者我应该怎么做? 他们是编写我的 Client 和 ClientsManager classes 的更好方法吗?
据我所知,如果无论如何我都想“自动装配”,有两种可能的方法。
- 对静态字段使用构造函数@Autowired
- 使用@PostConstruct 将值设置为静态字段
但是,当我想实例化“public static final ClientsManager manageClients = new ClientsManager();”
时,这是如何工作的?抱歉我的愚蠢问题,但我觉得我不完全理解这一点。
如果您想了解有关此主题的更多信息,请搜索 Spring 依赖注入,但我会写一个简短的摘要。
为了能够@Autowire 组件,您必须创建一个@Bean 或@Service 或@Component。
创建beand首先创建一个Configurationclass,然后在里面创建一个Beand或Beans
@Configuration public class Configuration { @Value("${configuration.property.name}") String username; @Bean public WebsocketServerEndpoint ebsocketServerEndpoint () { return new WebsocketServerEndpoint(); } }
@Value
不是必需的,只需提及此注释,您就可以从 spring application.properties
文件中获得 属性 名称。
此时您已经创建了 class 的 @Bean 实例,它被注册为单例 class。您可以从应用程序中的任何位置获取此一份副本 class,只需自动装配它即可。
或者基于用户构造器的依赖注入。 (@Autowired 不是首选)。
不要创建 bean,只需将
@Component
注释添加到您想要Autowire
的 class,但我显示了构造函数注入。@Component public class WebsocketServerEndpoint { public String test(){ return "test"; } } @RestController public class DoSomething { private final WebsocketServerEndpoint websocketHandler; public DoSomething(WebsocketServerEndpoint websocketHandler) { this.websocketHandler = websocketHandler; } @GetMapping(value = "/test") public String test() { return websocketHandler.test(); } }
您甚至可以使用 curl GET 请求测试此端点。 curl http://localhost:8080/test