如何创建可从其他类访问的 Websocket SessionManager
我正在开发一个带有 WebSocket 的应用程序,并希望将客户端 ID 和会话保存到管理器,但当我还希望能够使用自动装配从另一个类访问此内容时,很难理解如何正确执行此操作。
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);
}
....
....
....
....
}
来自另一个班级:
public class DoSomething {
@Autowired
WebsocketServerEndpoint serverEndpoint;
public String doSomething() {
int numberOfClients = serverEndpoint.getClients().size()
return numberOfClients;
}
}
据我了解。这是不正确的,您不应该自动装配静态字段等。
当我在 DoSomething 类中调试 serverEndpoint: null 时,我可以看到,但如果我有一个已连接的客户端,我会得到 1 个已连接的客户端,依此类推。 当我这样做时,我将在 DoSomething 课程中获得正确数量的客户。 我是否只是误解了这一点并且它像我所做的那样起作用? 或者我应该怎么做? 他们是编写我的 Client 和 ClientsManager 类的更好方法吗?
我读到,如果我想“自动装配”,无论如何有两种可能的方法。
- 使用构造函数 @Autowired 对于静态字段
- 使用 @PostConstruct 将值设置为静态字段
但是当我想实例化“public static Final ClientsManager manageClients = new ClientsManager();”时,这是如何工作的
抱歉我的愚蠢问题,但我觉得我不完全理解这一点。
I am working on an application with a WebSocket and want to save the clients id and session to a manager but have difficulties to understand how to do this correct when I also want to be able to reach this from another class with autowire.
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);
}
....
....
....
....
}
From another class:
public class DoSomething {
@Autowired
WebsocketServerEndpoint serverEndpoint;
public String doSomething() {
int numberOfClients = serverEndpoint.getClients().size()
return numberOfClients;
}
}
As I understand. This is not correct and you should not autowire static fields and so.
I can see when I debug that serverEndpoint: null in my DoSomething class but I get 1 connected client if I have one connected and so on.
When I do like this I will get the right number of clients in DoSomething class.
Have I just misunderstood this and it works as I have done?
or how should I do instead?
Is their a better way to write my Client and ClientsManager classes?
What I have read that if I would like to "Autowire" anyway there is two possible ways.
- Using Constructor @Autowired For Static Field
- Using @PostConstruct to set the value to Static Field
But how does this work when I would like to instantiate "public static final ClientsManager manageClients = new ClientsManager();"
Sorry for my stupid question but I feel I do not fully understand this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您想了解有关此主题的更多信息,请搜索 Spring 依赖注入,但我写了一个简短的总结。
为了能够 @Autowire 组件,您必须创建 @Bean 或 @Service 或 @Component。
创建bean首先创建一个Configuration类,以及里面的一个或多个Bean。
<前><代码>@配置
公共类配置{
@Value("${configuration.property.name}")
字符串用户名;
@豆
公共 WebsocketServerEndpoint ebsocketServerEndpoint () {
返回新的 WebsocketServerEndpoint();
}
}
@Value
不是必需的,只需使用此注释就可以从 springapplication.properties
文件中获取属性名称。之后,您已经创建了类的 @Bean 实例,它被注册为单例类。您可以从应用程序中的任何位置获取这一副本类,只需自动装配它即可。
或者基于用户构造函数的依赖注入。 (@Autowired 不是首选)。
不要创建bean,只需将
@Component
注释添加到您想要Autowire
的类中,但我显示了构造函数注入。<前><代码>@Component
公共类WebsocketServerEndpoint {
公共字符串测试(){
返回“测试”;
}
}
@RestController
公共类DoSomething {
私有最终WebsocketServerEndpoint websocketHandler;
公共 DoSomething(WebsocketServerEndpoint websocketHandler) {
this.websocketHandler = websocketHandler;
}
@GetMapping(值=“/测试”)
公共字符串测试(){
返回 websocketHandler.test();
}
}
您甚至可以使用curl GET 请求测试此端点。
卷曲http://localhost:8080/test
If you would like to understand more about this topic search for Spring Dependency injection, but I write a short summary.
To be able to @Autowire a component you have to create a @Bean or @Service or @Component.
Creating beands first create a Configuration class, and a Beand or Beans inside.
@Value
is not necessaty just good to mention with this annotation you can get a property name from springapplication.properties
file.After this point you have created a @Bean instance of your class it is registered as a singleton class. You can get this one copy class from anywhere in your application you just have to, autowire it.
Or user construcor based dependency injection. ( @Autowired is not prefered).
Dont create beans just add
@Component
annotation to your class that you want toAutowire
but I show a constructor injection.You can even test this endpoint with a curl GET request.
curl http://localhost:8080/test