I'm trying to ensure single worker session/window at a time.
In order to achieve this I have added a parameter closeExistingSessions to the createWorker and it's disconnecting (websocket) the other workerClient as expected.
Just wondering if there is a way to know the disconnect reason using this disconnected event listener so that I can show a relevant message to the end user.
const worker = new Twilio.TaskRouter.Worker(WORKER_TOKEN);
worker.on("disconnected", function(<ANY_ERROR_CODE_OR_SOMETHING_HERE?!>) {
console.log("Websocket has disconnected");
});
We are getting the reason (The reason the Worker websocket disconnected) as parameter to the disconnected callback.
const worker = new Twilio.TaskRouter.Worker(WORKER_TOKEN);
worker.on("disconnected", function(reason) {
console.log(reason.message);
});
And the reason for disconnecting due to existing sessions is 'Websocket disconnected due to new connection being registered'
Hope Twilio will keep their docs up to date
Related
I have developed a Quarkus app with which I want to receive and process MQTT messages.
This also works so far.
My problem is that when the internet goes down at the MQTT broker and the app reconnects afterwards, the app reconnects to the broker but no messages are received. I think that the "subscribe" method is not called anymore.
How can I solve this problem?
Here is my Config:
mp.messaging.incoming.smarthome/electricity.connector=smallrye-mqtt
mp.messaging.incoming.smarthome/electricity.host=192.168.1.88
mp.messaging.incoming.smarthome/electricity.port=1883
mp.messaging.incoming.smarthome/electricity.reconnect-attempts=3000
mp.messaging.incoming.smarthome/electricity.reconnect-interval-seconds=10
mp.messaging.incoming.smarthome/electricity.qos=1
mp.messaging.incoming.smarthome/electricity.failure-strategy=ignore
Here is my Controller:
#Incoming("smarthome/electricity")
public void consume(byte[] raw) {
String price = new String(raw,StandardCharsets.UTF_8);
String[] parts = price.split(",");
String watt = parts[0].trim();
String timeStamp = parts[1].trim();
byte wattH = Byte.parseByte(watt.replace("WH", ""));
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Europe/Vienna"))
.withHour(Integer.parseInt(timeStamp.split(":")[0]))
.withMinute(Integer.parseInt(timeStamp.split(":")[1]));
Message message = new Message(wattH,now);
System.out.println(message);
service.addToPackage(message);
scheudler.check();
}
Stack Output if i cut the Connection:
2022-09-20 07:50:09,683 ERROR [io.sma.rea.mes.mqtt] (vert.x-eventloop-thread-0) SRMSG17105: Unable to establish a connection with the MQTT broker: java.net.SocketException: Connection reset
If the Connection is back:
2022-09-20 07:50:26,751 INFO [io.ver.mqt.imp.MqttClientImpl] (vert.x-eventloop-thread Connection with 192.168.1.88:1883 established successfully
So the connection seems to be back, but there are no more incoming messages.
I solved the Problem by myself.
I set :
quarkus.arc.remove-unused-beans=none
And now it works fine.
I tried many ways to fix the problem, but this seems to be the issue.
I think there is some bean removed in the runtime when the connection is lost for a too long time.
If anyone can explain why this happens please tell me
We are using Lettuce in our project. We have a requirement to monitor the status of connection.
I know Lettuce can re-connect Redis when the connection is down. But is there some way to notify application that the connection is down/up?
Thanks,
Steven
Lettuce provides an event-model for connection events. You can subscribe to the EventBus and react to events published on the bus. There are multiple events, but for your case, you'd want to listen to connected and disconnected events:
ConnectionActivatedEvent: The logical connection is activated and can be used to dispatch Redis commands (SSL handshake complete, PING before activating response received)
ConnectionDeactivatedEvent: The logical connection is deactivated. The internal processing state is reset and the isOpen() flag is set to false.
Both events are fired after receiving Transport-related events such as ConnectedEvent respective DisconnectedEvent.
The following example illustrates how to consume these events:
RedisClient client = RedisClient.create()
EventBus eventBus = client.getresources().eventBus();
Disposable subscription = eventBus.get().subscribe(e -> {
if (e instanceOf ConnectionActivatedEvent) {
// …
}
});
…
subscription.dispose();
client.shutdown();
Please note that events are dispatched asynchronously. Anything that happens in the event listener should be non-blocking (i.e. if you need to call blocking code such as further Redis interaction, please offload this task to a dedicated Thread).
Read more
Lettuce Reference Documentation: Events
I am using Chrome 66.0.3359.181 (64-bit). I am running the following code:
navigator.serviceWorker.ready
.then(sw=>{
addData('sync-posts',post)
.then(()=>{
return sw.sync.register('sync-new-posts');
})
.then(()=>{
var snackbarContainer = document.querySelector('#confirmation-toast');
const data = {message: 'Your post was saved for syncing!'};
snackbarContainer.MaterialSnackbar.showSnackbar(data);
})
.catch(err=>{
console.log(err);
});
})
However even when I have disconnected my wifi it still triggers the sync event immediately.
ANSWER: I actually figured this out while I was writing it but since I didn't find anyone else answer this type of question AND it took an hour or so out of my time I thought I'd post it anyway.
I had a VM network adapter enabled (for Docker) and that was causing it to try and sync even though that connection didn't go anywhere useful.
Then I also discovered that provided I was throwing an error from that sync event when it failed, it would retry syncing. Originally I was catching errors and just logging to console but this meant the sync thought it was complete.
I'm trying to establish a communication channel between an installing service worker and an activated service worker.
I've tried to do the following:
on the installing service worker:
if ((self.registration.active == null) ||
(self.registration.active.state != "activated")) {
return;
}
var messageChannel = new MessageChannel();
messageChannel.port1.onmessage = function(event){
if (event.data.error) {
console.log("got error from active");
}
else {
console.log("got answer from active");
}
};
self.registration.active.postMessage({message: 'hey', port: messageChannel.port2}, [messageChannel.port2]);
on the active service worker:
self.addEventListener('message', function(event) {
console.log('received message');
});
This isn't working, I'm getting nothing...
Ideas?
Here's how I ended up implementing this.
Each serviceWorker at startup (code at the worker's global scope) connects to a broadcast channel like so:
var comChannel = new BroadcastChannel('SWCom');
comChannel.addEventListener('message', event => {
handleMessageEvent(event);
});
This channel is shared only between service workers.
To post a message to other SW, a SW can just broadcast on the channel comChannel.postMessage('hey there'); and any registered listener will be invoked.
One complication I had, not really related to the channel, is that I had a hard time identifying each SW life cycle state. If I want to communicate between SW it can't really serve any purpose if I don't know who's whom within each one of them. A SW cannot currently get a ref to its own ServiveWorker object, there's an open issue about it in the standard - https://github.com/w3c/ServiceWorker/issues/1077
In my usecase, I bypassed this limitation by performing the communication upon install (fits my needs...), like so:
self.addEventListener('install', function(event) {
if (self.registration.active != null) {
// if we got here it means this is a new SW that's
// starting install and there's an active one running.
// So we can send a message on the broadcast channel,
// whomever answers should be the active SW.
}
// ..
// installation code
// ..
}
One thing to note - I'm not sure this is well implemented.
I believe there are other states a SW can be at (redundant, deleted?, others?), so maybe there can be more then two ServiceWorkers alive, and then the assumption on the identity of the answering side on the channel might be wrong...
Jake provides some excellent examples of messaging that you may be able to derive a solution from. https://gist.github.com/jakearchibald/a1ca502713f41dfb77172be4523a9a4c
You may need to use the page itself as a proxy for sending/receiving messages between Service workers:
[SW1] <== message ==> [Page JS] <== message ==> [SW2]
There are running examples of SignalR, but in those, i have seen that the process is started by the client i.e. every piece of code contains following similar lines
$.connection.hub.start().done(function () {
$('#mybutton').click(function () {
notifier.server.doLongOperation();
});
});
The process on server starts on $('#mybutton').click and then responds.
Is my understanding correct? If yes then is it possible to start the process by Server? I mean Server will push messages to all clients without any triggering from the client side.
This didn't work
var context = GlobalHost.ConnectionManager.GetHubContext<Broadcast>();
context.Clients.All.Send(message);
My bad, method name on client side was incorrect. Problem solved
Yes it is possible to send server initiated "messages" from the server to clients. Note that you have to call a method on the client. Note that it's a RPC/Remoting type of communication.
On the server you'd have a code like this:
Clients.All.Say("Hello World!");
where the client needs to define a function:
myHub.client.say = function (message) {
console.log(message);
});
see the SignalR documentation