Dealing with users instead of connectors_0.2.1
Bristleback's goal is to provide high level abstraction for dealing with WebSocket internal mechanisms. One of the most important parts of creating application is handling clients request. Brisleback provides convenient API for dealing with WebSocket connectors. You don't have to use that low level mechanism, instead we're providing default classes for most common use cases, as well as possibility to customize them.
Main interface representing user connected to BristleBack server is named IdentifiedUser. Provides user friendly abstraction for dealing with low level WebSocket mechanism.
For each WebSocket connection new instance of IdentifiedUser is created. Framework user can create own implementation of this interface. If there is no implementation of IdentifiedUser, instance of class pl.bristleback.server.bristle.engine.base.users.DefaultUser will be created.
Default implementation provides minimal set of methods that are required by framework specification (getId method implemented).
UserFactory is an interface used by Bristleback framework to create new instance of user. When new WebSocket connection is opened it creates new instance of IdentifiedUser. If you want to use your own implementation of user object you should implement this interface and specify created class in configuration. If there is no implementation of UserFactory, pl.bristleback.server.bristle.engine.base.users.DefaultUserFactory will be used by framework.
If you want your own customized user object you need to implement two interfaces IdentifiedUser and UserFactory. IdentifiedUser requires implementation of getId. That method must return unique id number for each connected user. Default implementation uses UUID to generate random identifier.
package pl.bristleback.server.bristle.api.users; public interface IdentifiedUser { String getId(); }
UserFactory is responsible for creation if new instance of user object. For every new WebSocket connection it should return unique instance of your own implementation of IdentifiedUser.
package pl.bristleback.server.bristle.api.users; public interface UserFactory { IdentifiedUser createNewUser(); }
To sum up, required steps are (reference implementation provided)
import pl.bristleback.server.bristle.api.users.IdentifiedUser; import java.util.UUID; public class DefaultUser implements IdentifiedUser { private String id; public DefaultUser() { this.id = UUID.randomUUID().toString(); } @Override public String getId() { return id; } }
import pl.bristleback.server.bristle.api.users.IdentifiedUser; import pl.bristleback.server.bristle.api.users.UserFactory; public class DefaultUserFactory implements UserFactory { @Override public IdentifiedUser createNewUser() { return new DefaultUser(); } }
Your custom factory can be set as any other Bristleback configuration param. Just specify in your Spring context file:
<bean id="myUserFactory" class="your.package.OwnFactoryClass"/> <bean id="initPojoConfigResolver" class="pl.bristleback.server.bristle.conf.resolver.init.PojoConfigResolver"> <property name="userFactory" value="myUserFactory"/> </bean>
You can also use properties files with DefaultConfigurationResolver. For detailed description please refer to Bristleback configuration
You may want to define special type of action when user is connecting or disconnecting to server. In order to do so you can implement following interface.
package pl.bristleback.server.bristle.api; public interface ConnectionStateListener<T extends IdentifiedUser> { /** * Method invoked after connection with given user is established. * * @param identifiedUser connected user. */ void userConnected(T identifiedUser); /** * Method invoked <strong>after</strong> connection with given user is closed. * In addition, user doesn't exists in users container and cannot receive any further messages. * * @param identifiedUser disconnected user. */ void userDisconnected(T identifiedUser); }
All implementations of that interface defined as Spring Beans will be used by Bristleback.
Remember: order of connection state listeners execution cannot be determined!