In my project I am trying to implement a event handling for my websocket instances. So I basically have 3 classes:
My AuthClient class which extends a WebsocketClient and has onMessage callback. In this onMessage method the websocket can enter different states like "hello", "pending_finish", "finish" and so on.
public class AuthClient extends WebSocketClient {
#Override
onMessage(String message) {
switch(message) ... // data events here
}
}
I am now trying to write a parent class called ClientManager where I want to store and manage multiple websockets.
// trying to receive data from specific data events for each client here
public class ClientManager {
private int maxClients;
private final Map<String, AuthClient> clients;
private final HashSet<String> tokens;
public ClientManager(HashSet<String> tokens, int maxClients) {
this.tokens = tokens;
this.maxClients = maxClients;
this.clients = new HashMap<>(maxClients);
}
}
My question is, how can I pass data which I receive from a WebsocketClient within this onMessage callback to my ClientManager? I need a solution that does not have any great performance loss.
I already tried implementing an interface with the events, but I don't quite get it to work with sharing data.
This looks like a good use case for an observer pattern.
Your observer would be your manager class and your observables would be your websocket clients. Any time you create a new websocket client, register your manager class instance with it using the registerObserver method. Then when you desire to forward a message from your websocket client to your manager, you can simply call the notifyObservers method to forward the request out to any registered observers. Take a look at the pattern info here:
https://www.baeldung.com/java-observer-pattern
Related
I am implementing a client application to automate trading tasks in InteractiveBroker(IB) platform. They are providing us with standalone application called TradingWorkStation(TWS) and a library to implement our own client applications. But our client application cannot directly communicate with IB platform on its own, client app has to pass our message to TWS application and TWS handles the communication with the actual IB platform.
IB library provides us with EClientSocket interface, which has methods to communicate with TWS application. But they are asynchronous calls with no responses. When TWS needs to send back responses, it calls EWrapper interface of client application.
Refer to following diagram,
I am using Spring Boot to develop this client application. I have TraderService class which has eClient object as a attribute to communicate with TWS app. And I need to ask for contract details from TWS to initiate the trading process. I need TraderService constructor to continue only of these requested contract details are available.
Refer to TraderService below,
#Service
public class TraderService {
private final IBEventWrapper eventWrapper;
private final EClientSocket socket;
public TraderService() {
this.eventWrapper = new IBEventWrapper();
this.socket = new EClientSocket(eventWrapper);
socket.eConnect('localhost', 7497, 1);
if (socket.isConnected()) {
logger.info("connected..");
// requesting contract details, but return type is void
socket.reqContractDetails();
// continue only if contract results are available ...
}
}
}
Notice here, reqContractDetails method does not have a return type, and actual results are received to EWrapper interface implementation.
Refer to EWrapper implementatin below,
public class IBEventWrapper implements EWrapper {
private final TraderService traderService;
public IBEventWrapper(TraderService traderService) {
// trying to pass results back to trader service
this.traderService = traderService;
}
// this method is invoked by TWS to return contract results
#Override
public void contractDetails(int reqId, ContractDetails contractDetails) {
logger.info("contractDetails {}", reqId);
}
}
As seen above, EWrapper methods are invoked by TWS app, when results are available. But I need to pass them back to TraderService constructor.
Is there any approach (may be from Spring boot) to make this happen.
IB TWS API is publish–subscribe based, you will have to make requests and await the data to return. I have been using CountDownLatch like this (in your handler class):
private CountDownLatch latch = new CountDownLatch(1);
public String getGenericTick() {
return genericTick;
}
public CountDownLatch getLatch() {
return latch;
}
#Override
public void tickString(TickType tickType, String value) {
if (tickType == TickType.FUNDAMENTAL_RATIOS) {
genericTick = value;
latch.countDown();
}
}
Which allows you to know if the data is available or explicitly await for some time (3s is usually enough for anything within a single request):
var handler = new FundamentalsRatiosDataHandler();
controller.reqTopMktData(contract, "258", false, false, handler);
if (!handler
.getLatch()
.await(3, TimeUnit.SECONDS)) {
// failure
}
Look at the following use case.
I have a client (Java) application, which wants to get/set the state of another, remote application (C). The communication between them is done via SIP, which is run in another thread.
The SIP interface can do the following:
sendMessage
onRequest
I have two ideas for the architecture:
RPC (JSON-RPC)
Define a class which does the marshalling/unmarshalling for JSONRPCRequests and JSONRPCResponse (http://software.dzhuvinov.com/json-rpc-2.0-base.html)
Define a Invoker class, which has something like a call(server, name, arguments) method.
In the Invoker class, the name and arguments are put into a JSONRPCRequest and sent via the SIP layer sendMessage
Now comes my problem. How do i actually get the right back to the caller? The control flow is now:
The onRequest method is called, but I do now know whether it is the answer to my previous call. What i do is putting all responses reaching my server into a Map, and just poll that list in the Invoker.
A rough sketch might be;
Invoker (provides API to client)
class Invoker {
private Channel channel;
public Invoker(Channel channel) { this.channel = channel; }
public Object call(String server, String name, Object .. args) {
JSONRPCRequest req = ...;
channel.sendMessage(server, req.toString());
while( ! channel.hasResponse(req.id()) {
Thread.sleep(42);
}
return channel.getResponse(req.id()).result();
}
}
Channel (interface to messenger):
class Channel {
private Map<Object, JSONRPCResponse> responses = new //;
private Sip sip = new Sip() {
public void onRequest(String msg) {
JSONRPCResponse response = JSONRPCResponse.parse(msg);
responses.put(msg.id(), response);
}
};
public void sendMessage(String server, String message) {
sip.sendMessage();
}
public boolean hasResponse onRequest(Object id) {
responses.hasKey(id);
}
public JSONRPCResponse getResponse(Object id) {
responses.get(id);
responses.delete(id);
}
}
SIP (messenger itself):
abstract class Sip {
public void sendMessage(String msg) {
// SIP magic
}
public abstract void onRequest(String msg);
}
Is there a better way to do that? My biggest problems/code smells are:
the blocking in Invoker
the protocol is in Invoker, maybe I want to switch marshalling to something else
the map as mean to get the correct response for a request
the SIP abstract method looks strange
No error handling
No timeout
Message Passing
Is there an easy way to get rid of RPC, and implement something like RPC with just message passing? Any hints for pattern are welcome. I do not need the code itself, I am totally fine with just architecture. I tried to google for message passing implementations, and how they actually change state with it, but I did not find anything useful. How to implement timeout/ error handling?
Any good books/literature on that topic is also welcome, as I never programmed such distributed stuff.
Any other ideas on which protocol to use inside SIP to change state is welcome, too, as RPC was my initial thought, and I did not find anything other useful.
The code will not compile, I guess, it was just to visualize my idea.
Define a service interface that has meaningful (for the us case) methods. Instead of using blocking calls, have the client supply a ResponseHandler that will be invoked when the operation is complete:
interface ResponseHandler {
void onComplete(Response response);
void onError(Throwable error);
}
interface SomeService {
void set(String attribute, Object value, ResponsHandler responseHandler);
void get(String attribute, ResponseHandler responseHandler);
}
The implementation of the Service interface can use any suitable protocol, but it has to correlate requests with responses in order to invoke the correct callbacks.
I have Threads that listens to incoming HTTP messages , i want to enable other developer that use my code to be able to use the messages that i received in any time. I saw in some mobile OS you can implement class and override onRecive function to receive the messages .
is this the right architecture to use in this case? if yes how could i implemented and if its not what is the best way to do it.
You can have a interface which another develoepr can implement and register with your code to be notified when a new message etc has arrived. There are any number of ways this can be achieved.
You could use the built in Observable class. or you could do something like this.
public interface Listener<T> {
public void onEvent(T t);
}
public class Listenable<T> {
private final List<Listener<T>> list = new CopyOnWriteArrayList<Listener<T>>();
public void register(Listener<T> listener) {
if (!list.contains(listener)) list.add(listener);
}
public void unregister(Listener<T> listener) {
list.remove(listener);
}
public void onEvent(T t) {
for (Listener<T> tListener : list)
tListener.onEvent(t);
}
}
The caller could implement the Listener interface or provide an object which does. It then registers this with the Listenable. The listenable can notify all registered listeners.
Take a look at the Observer Pattern.
You can have an interface called MessageListener:
public interface MessageListener{
void onMessage(String message);
}
Users of your library will create their own MessageListeners and will implement the onMessage method which defines what should be done when a message is received. They will also set (or register) this MessageListener with your "threads" before they are started.
Now whenever your thread gets a message, it will notify the listener(s) registered with it by calling the onMessage method.
I have this situation:
interface MessageListener
{
void onMessageReceipt(Message message);
}
class MessageReceiver
{
MessageListener listener;
public MessageReceiver(MessageListener listener, other arguments...)
{
this.listener = listener;
}
loop()
{
Message message = nextMessage();
listener.onMessageReceipt(message);
}
}
and I want to avoid the following pattern: (Using the this in the Client constructor)
class Client implements MessageListener
{
MessageReceiver receiver;
MessageSender sender;
public Client(...)
{
receiver = new MessageReceiver(this, other arguments...);
sender = new Sender(...);
}
.
.
.
#Override
public void onMessageReceipt(Message message)
{
if(Message.isGood())
sender.send("Congrtulations");
else
sender.send("Boooooooo");
}
}
The reason why i need the above functionality is because i want to call the sender inside the onMessageReceipt() function, for example to send a reply. But I dont want to pass the sender into a listener, so the only way I can think of is containing the sender in a class that implements the listener, hence the above resulting Client implementation. Is there a way to achive this without the use of 'this' in the constructor? It feels bizare and i dont like it, since i am passing myself to an object(MessageReceiver) before I am fully constructed. On the other hand, the MessageReceiver is not passed from outside, it is constructed inside, but does this 'purifies' the bizarre pattern?
I am seeking for an alternative or an assurance of some kind that this is safe, or situations on which it might backfire on me.
The Client's dependencies (such as MessageReceiver) could be injected into it rather than having the Client know how to construct the MessageReceiver:
Client client = new Client(...);
MessageReceiver rcvr = new MessageReceiver(client, ...);
client.setMessageReceiver(rcvr);
However I would suggest looking into breaking the circular dependency between these two classes, it sounds as if something is off in your design.
The real reason why passing this to another class in the first class's constructor is a bad practice is because you are allowing a reference to this to escape before it is fully constructed.
It wont backfire on you as long as this is never referenced before construction. However, you should never rely on that assumption. Concurrency is a big factor here, as well as the contract for the code you pass it to.
Since Client is a MessageReceiver, why not make it one?
public Client extends MessageReceiver implements MessageListener{
/* ... */
}
I don't see where the MessageReceiver is used, so at the moment you could write the code without MessageReceiver like this and it would be effectively the same:
interface MessageListener
{
void onMessageReceipt(Message message);
}
class Client implements MessageListener
{
MessageSender sender;
public Client(...)
{
sender = new Sender(...);
}
.
.
.
#Override
public void onMessageReceipt(Message message)
{
if(Message.isGood())
sender.send("Congrtulations");
else
sender.send("Boooooooo");
}
}
I think a standard publish-subscribe or Observer pattern is probably what you need - but it's hard to tell without understanding the subtleties of the problem that you are trying to solve.
UPDATED: Added one more question (Question #4).
Hi all,
I'm building myself a custom emailing utility. Now, to obey Single Responsibility Principle, I want to have the following classes: MailerSender, MailProvider and EmailObject. The MailSender is more of a delegate, check it out below:
public class MailSender {
private IMailProvider mailProvider;
public void setMailProvider (IMailProvider provider) {
this.mailProvider = provider;
}
// option to set it up during construction
public MailSender (IMailProvider provider) {
this.mailProvider = provider;
}
public void sendEmail(EmailObject obj) {
if(mailProvider == null)
throw new RuntimeException("Need a mail provider to send email.");
try {
mailProvider.send(obj);
} catch (Exception e) {
// do something here
}
}
}
The MailSender requires an IMailProvider email provider that does the work of sending the email. Find it below:
public interface IMailProvider {
public void sendEmail(EmailObject obj);
}
public class SMTPEmailProvider implements IMailProvider {
public void sendEmail(EmailObject obj) {
// use SMTP to send email using passed-in config
}
}
public class JMSEmailProvider implements IMailProvider {
public void sendEmail(EmailObject obj) {
// push emails to JMS queue to be picked up by another thread
}
}
I have defined a few strategies above, but it can be extended to any number. Since the MailSender can change it's provider at any time, it effectively implements the strategy pattern right?
The EmailObject is a POJO containing relavent email information:
public class EmailObject {
private String to;
private String from;
private String cc;
private String subject;
private String body;
// setters and getters for all
}
Client code will then look like:
MailSender sender = new MailSender(new SMTPMailProvider());
sender.send(new EmailObject());
sender.setMailProvider(new JMSMailProvider());
sender.send(new EmailObject());
My questions are:
1. Have I implemented the Strategy Pattern?
2. Is this design good? Does it make sense for a MailProvider to be aware of an EmailObject?
3. What if I had a new EmailObject later on that required an attachment?
4. The client code now needs to acquire a specific MailProvider before creating a MailSender ... does this make sense?
Ok, let's go through your questions.
1) Vaguely, yes. You could argue that you have "algorithms" or "strategies" and that you can pick between them. However, I prefer to think of the strategy pattern as something that is relevant to algorithms. For example, different ways to get a search result. Here you are dealing with different agents to which you delegate the role of sending email. That's a common design, but I am not sure I would necessarily call it strategy. Either way, design patterns are meant to help you think, not to lock you to a specific name.
2) I think the design is reasonable. I would use interfaces rather than actual classes, especially for the EMailObject. In addition, there should be a factory for email object, don't just new them. It is also very likely that each provider will provide it's own "email object" that includes package detail. You are sending the contents, not the "envelope".
3) That's another good reason to use interfaces rather than a class. And you may want to include getters/setters for metadata and potentially attachments because they are a legitimate part of your domain (an email).
The most important questions here are in my opinion:
Can you test your component without sending actual emails? Yes:
MailSender sender = new MailSender(new FakeMailProvider());
sender.send(new EmailObject());
Can you test your email providers without the rest of the application? Yes:
SMTPMailProvider provider = new SMTPMailProvider();
provider.send(new EmailObject());
You have succesfully decoupled providers from senders.
EDIT: Q4. The client needs to pass the specific MailProvider to the MailSender before sending EmailObject. This statement can be transformed into something like this: "client asks the emailing service to send the email, passing email data and choosing a transport (a way to send an email)". I think it is OK, but if you don't want to specify the transport every time, you may change it to "... the service then sends the email using the configured transport" and move provider instantiation to the configuration.