I was trying to connect SSE from android app but it have a problem.
It is not showing data 100%. Like in first attempt someone trigger notify command then it won't work but after that second attempt everybody get notify.
Here is my code:
//calling this code from activity on create
EventHandler eventHandler = new SimpleEventsListener();
String url = String.format(ApiInterface.ENDPOINT + "notify/");
EventSource.Builder builder = new EventSource.Builder(eventHandler, URI.create(url)).connectTimeoutMs(29 * 1000);
try (EventSource eventSource = builder.build()) {
for (; ; ) {
eventSource.start();
TimeUnit.SECONDS.sleep(30);
}
}
here is EventSource implementation.
public class SimpleEventsListener implements EventHandler {
#Override
public void onOpen() throws Exception {
System.out.println("SimpleEventsListener onOpen ");
}
#Override
public void onClosed() throws Exception {
System.out.println("SimpleEventsListener onClosed");
}
#Override
public void onMessage(String event, MessageEvent messageEvent) throws Exception {
System.out.println("SimpleEventsListener Event received " + messageEvent.getData());
// here implemented data recieved code which coming from messageEvent.getData()
}
#Override
public void onComment(String comment) throws Exception {
System.out.println("SimpleEventsListener onComment");
}
#Override
public void onError(Throwable t) {
System.out.println("SimpleEventsListener onError: " + t);
}
}
What is the of best way to receive data on the first attempt too?
Related
I'm using the packages:
// Apollo
implementation "com.apollographql.apollo:apollo-runtime:2.4.1"
implementation "com.apollographql.apollo:apollo-rx3-support:2.4.1"
// RxJava
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.4'
And I call function:
public static Flowable<Response<CallSubscription.Data>> callSubscription(String room) {
ApolloSubscriptionCall<CallSubscription.Data> call = getApolloClient()
.subscribe(new CallSubscription(room));
return Rx3Apollo.from(call)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext((dataResponse -> {
System.out.println("datat" + dataResponse);
if (dataResponse.getErrors() != null) {
throw new ApolloException(dataResponse.getErrors().get(0).getMessage());
}
}))
.filter((dataResponse -> dataResponse.getData() != null));
}
which is used here:
NetworkService.callSubscription(room).subscribeWith(new DisposableSubscriber<Response<CallSubscription.Data>>() {
#Override
protected void onStart() {
super.onStart();
System.out.println("onStart");
}
#Override
public void onNext(#NonNull Response<CallSubscription.Data> dataResponse) {
System.out.println("onNext " + dataResponse);
}
#Override
public void onError(#NonNull Throwable e) {
System.out.println("onError " + e);
}
#Override
public void onComplete() {
System.out.println("onComplete ");
}
});
And I need to handle exception from NodeJs inside subscription resolver, which is throw new NotFoundException('SOME_ERROR');, but I got just "onStart", nothing else (no "onNext", "onError", "onComplete"). While playground works fine and I'm handling exception there, and query and mutations also work fine with exceptions. What happened with Rx3Apollo subscriptions? it's my mistake or this package has bug?
I am trying to implement a CoAP client based on Californium. I make this client observing to a resource:
public static class CoapCl{
double val = 0;
CoapClient client = new CoapClient("coap://localhost/Ultrasonic");
CoapObserveRelation relation = client.observe(new CoapHandler() {
#Override public void onLoad(CoapResponse response)
{
val = Double.parseDouble(response.getResponseText());
}
#Override
public void onError() {
System.out.println("Failed");
}
});
}
I want to access the value "val" from another class. How can I do it ? I tried to call a reference from the CoapCl class like this and print the value out:
CoapCl client = new CoapCl();
while(true)
{
System.out.println("Testing: " + client.val);
}
This will print all the value I get from the CoAP client, both changed and unchanged value. What should I do if I only want to get the changed value ?
Well, the issue itself isn't related to Californium and CoAP.
Except that CoapHandler is async but this is rather a strench.
Nevertheless, I'd recommend to end up with some kind of callback:
public class CoapCl {
private final Consumer<Double> valueChangedAction;
private final CoapClient client = new CoapClient("coap://localhost/Ultrasonic");
public CoapCl(Consumer<Double> valueChangedAction) {
this.valueChangedAction = valueChangedAction;
}
public void run() {
client.observe(new CoapHandler() {
#Override
public void onLoad(CoapResponse response) {
valueChangedAction.accept(
Double.parseDouble(
response.getResponseText()
)
);
}
#Override
public void onError() {
System.out.println("Failed");
}
});
}
}
new CoapCl(val -> System.out.println("Testing: " + val)).run();
Please keep in mind you have to block the main thread someway to keep the program from immediate exit.
Before, you had blocked it with your infinite loop.
Now you'll have to use System.in.read() or Thread.sleep or something else if you have no such stuff yet in your program.
How can you create a failsafe Spring XD stream, which will keep running properly after an exception is triggered for one specific message (i.e.logs the error but continues consuming the next messages in the stream), without having to add try catch(Throwable) in every Stream step?
Is there any easy way of doing this with the Reactor or RxJava model?
Example stream using Reactor:
#Override
public Publisher<Tuple> process(Stream<GenericMessage> inputStream) {
return inputStream
.flatMap(SomeClass::someFlatMap)
.filter(SomeClass::someFilter)
.when(Throwable.class, t -> log.error("error", t));
}
RxJava can be used by a processor module. On creation the subscription needs to be created and to handle errors the subscriber needs to add an onError handler:
subject = new SerializedSubject(PublishSubject.create());
Observable<?> outputStream = processor.process(subject);
subscription = outputStream.subscribe(new Action1<Object>() {
#Override
public void call(Object outputObject) {
if (ClassUtils.isAssignable(Message.class, outputObject.getClass())) {
getOutputChannel().send((Message) outputObject);
} else {
getOutputChannel().send(MessageBuilder.withPayload(outputObject).build());
}
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
logger.error(throwable.getMessage(), throwable);
}
}, new Action0() {
#Override
public void call() {
logger.error("Subscription close for [" + subscription + "]");
}
});
Look at more examples here: https://github.com/spring-projects/spring-xd/tree/master/spring-xd-rxjava/src
I'm very new with Vert.x so excuse my newbness.
I was able to create a very simply SockJS server with Vert.x however I can't figure out how to register events/callbacks/handlers when connections are open or closed.
With JSR-356, it's drop dead simple to handle open/close connection events:
#OnOpen
public void onOpen(Session userSession) {
// Do whatever you need
}
#OnClose
public void onClose(Session userSession) {
// Do whatever you need
}
Using the SockJS support in Spring Framework 4.0 M1+, it's almost the same as JSR-356:
public class MySockJsServer extends TextWebSocketHandlerAdapter {
#Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// Do whatever you need
}
#Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// Do whatever you need
}
}
For some reason I couldn't figure out how to do something so conceptually simple in Vert.x. I though Vert.x was simple ?!!
If anyone can point me in the right direction, please help.
I played around with EventBus and EventBus hooks but it didn't work. Perhaps that's the wrong approach anyhow.
I'm using Vert.x version 2.0.1
TIA
This is the answer:
HttpServer httpServer = vertx.createHttpServer();
// Create HTTP server
httpServer = httpServer.requestHandler(new Handler<HttpServerRequest>() {
#Override
public void handle(HttpServerRequest req) {
req.response().sendFile("web/" + req.path());
}
});
// Create SockJS Server
SockJSServer sockJSServer = vertx.createSockJSServer(httpServer);
sockJSServer = sockJSServer.installApp(new JsonObject().putString("prefix", "/test"), new Handler<SockJSSocket>() {
public void handle(final SockJSSocket sock) {
System.out.println("New session detected!");
// Message handler
sock.dataHandler(new Handler<Buffer>() {
public void handle(Buffer buffer) {
System.out.println("In dataHandler");
}
});
// Session end handler
sock.endHandler(new Handler<Void>() {
#Override
public void handle(Void arg) {
System.out.println("In endHandler");
}
});
}
});
httpServer.listen(8080);
I'm trying to write a servlet that uses org.apache.catalina.websocket.WebSocketServlet. I've found an example of websocket chat, but I can't figure out how can I specify the listening port for a websocket server (which is implemented in this servlet)? For example I need to listen for clients connection on port 11337. But how I can express this?
OK, here is the (simplified) code:
public class TestServlet extends WebSocketServlet {
private static final Logger logger = LoggerFactory.getLogger(TestServlet.class);
public TestServlet() {
logger.error("Initializing TestServlet");
}
#Override
protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest request) {
logger.error("New WS connection, subProtocol=" + subProtocol + ", request=" + request.getRequestURL());
return new TestConnection();
}
private class TestConnection extends MessageInbound {
#Override
protected void onBinaryMessage(ByteBuffer byteBuffer) throws IOException {
logger.error("onBinaryMessage");
}
#Override
protected void onTextMessage(CharBuffer charBuffer) throws IOException {
logger.error("onBinaryMessage: " + charBuffer);
sendMessage("Test message");
}
public void sendMessage(String message) {
WsOutbound outbound = this.getWsOutbound();
CharBuffer cb = CharBuffer.wrap(message);
try {
outbound.writeTextMessage(cb);
} catch (IOException e) {
logger.error("failed to write outbound");
}
}
}
}
I can't find where and how I can set listening port. Official websocket documentation also doesn't help much.
So I guess it can be set somewhere in servlet settings, but can't find where.
Does anyone have any ideas?
WebSocket is designed to work over HTTP protocol and so it won't have different listening port like normal TCP Socket but it use the same server port that it deployed on.
so here in your case, if you are using tomcat server than websocket may use port 8080 (if you haven't modified explicitly) for communication. You may need to override onOpen and onClose methods of MessageInbound class to get notified on Connection established and connection close. Refer below sample code for more details.
public class IncomingMessageHandler extends MessageInbound {
private WsOutbound myoutbound;
public IncomingMessageHandler() {
}
#Override
public void onOpen(WsOutbound outbound) {
logger.info("Open Client.");
this.myoutbound = outbound;
}
#Override
public void onClose(int status) {
logger.info("Close Client.");
}
/**
* Called when received plain Text Message
*/
#Override
public void onTextMessage(CharBuffer cb) throws IOException {
}
/**
* We can use this method to pass image binary data, eventually !
*/
#Override
public void onBinaryMessage(ByteBuffer bb) throws IOException {
}
public synchronized void sendTextMessage(String message) {
try {
CharBuffer buffer = CharBuffer.wrap(message);
this.getMyoutbound().writeTextMessage(buffer);
this.getMyoutbound().flush();
} catch (IOException e) {
}
}
/**
* Set timeout in milliseconds, -1 means never
*/
#Override
public int getReadTimeout() {
return -1;
}
public WsOutbound getMyoutbound() {
return myoutbound;
}
public void setMyoutbound(WsOutbound myoutbound) {
this.myoutbound = myoutbound;
}
}