i am using grails 3.1.1
i already try to find some documentation and question like this.
this is my code in ChatController
class ChatController {
SimpMessagingTemplate brokerMessagingTemplate
def corporateUserService
def index={
}
#MessageMapping("/chat")
#SendTo("/queue/chat")
protected String hello(DestinationUser map) {
brokerMessagingTemplate.convertAndSend "/queue/chat", map
}
}
and i already deploy this application, for example :
https://somedomain.com
how can i connect from android to my webapplication's websocket?
i tried
wss://somedomain.com/chat
wss://somedomain.com/queue/chat
but it still cannot connect.
i am trying follow this tutorial github
like this..
AsyncHttpClient.getDefaultInstance().websocket("ws://satubangau.com/app/hello", null, new AsyncHttpClient.WebSocketConnectCallback() {
#Override
public void onCompleted(Exception ex, WebSocket webSocket) {
Log.d(TAG, "onCompleted: ");
if (ex != null) {
ex.printStackTrace();
return;
}
webSocket.send("a string");
webSocket.send(new byte[10]);
webSocket.setStringCallback(new WebSocket.StringCallback() {
public void onStringAvailable(String s) {
Log.d(TAG, "onStringAvailable: I got a string: " + s);
}
});
webSocket.setDataCallback(new DataCallback() {
public void onDataAvailable(DataEmitter emitter, ByteBufferList byteBufferList) {
Log.d(TAG, "onDataAvailable: I got some bytes!");
// note that this data has been read
byteBufferList.recycle();
}
});
}
});
but i get the log like this..
Have you tried using a WebSocket client library on Android, e.g. https://github.com/koush/AndroidAsync ?
Related
How to programatically (java) prevent specific errors messages to be sent to Sentry? I want, for example, do not send to Sentry errors with the word "any_example_word". It's important to know that filtering by error message is not enabled in the User Interface.
I'm using Sentry 1.7.23, but all examples I can find use latest version (4.*), which are tottaly different. They use classes and methods that do not exist in this old version.
I don't know if this is relevant, but my application runs over thorntail and it uses jdk 8.
Edit:
I'm trying to do this:
#WebListener
public class MyContextListener implements ServletContextListener {
private static SentryClient sentryClient = SentryClientFactory.sentryClient();
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
Sentry.init();
String testStrings = "ipsis litteris;some_error_message";
String[] messagesToIgnore = StringUtils.split(testStrings, ';');
sentryClient.addShouldSendEventCallback(new ShouldSendEventCallback() {
#Override
public boolean shouldSend(Event event) {
for (Map.Entry<String, SentryInterface> interfaceEntry : event.getSentryInterfaces().entrySet()) {
if (interfaceEntry.getValue() instanceof ExceptionInterface) {
ExceptionInterface i = (ExceptionInterface) interfaceEntry.getValue();
for (SentryException sentryException : i.getExceptions()) {
for (String msgToIgnore : messagesToIgnore) {
if (StringUtils.contains(sentryException.getExceptionMessage(), msgToIgnore)) {
return false;
}
}
}
}
}
return true;
}
});
Sentry.setStoredClient(sentryClient);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Question 1) Is this the correct place to initialize Sentry?
Question 2) Why ShouldSendEventCallback is lost? Looking at
io.sentry.SentryClient:
public void sendEvent(Event event) {
for (ShouldSendEventCallback shouldSendEventCallback : shouldSendEventCallbacks) {
if (!shouldSendEventCallback.shouldSend(event)) {
logger.trace("Not sending Event because of ShouldSendEventCallback: {}", shouldSendEventCallback);
return;
}
}
try {
connection.send(event);
} catch (LockedDownException | TooManyRequestsException e) {
logger.debug("Dropping an Event due to lockdown: " + event);
} catch (Exception e) {
logger.error("An exception occurred while sending the event to Sentry.", e);
} finally {
getContext().setLastEventId(event.getId());
}
}
In some point during app execution, sentryClient is reinitialized and shouldSendEventCallbacks becomes empty, what causes my messages not being filtered.
So I get back to question 1, since apparently sentry configuration is not being persistent.
I am trying to get a GraphQL subscription working with Java/Vert.x and to have the results shown in GraphiQL. I see all the System.out.println statements in the console, but GraphiQL is not displaying any results because the server is generating an 'Internal Server Error' message.
Schema:
type Subscription {
test: String
}
Vert.x Verticle
private RuntimeWiring getRuntimeWiring() {
return new RuntimeWiring()
.type("Subscription", builder -> builder
.dataFetcher("test", getTestDataFetcher()))
.build();
}
private VertxDataFetcher<Publisher<String>> getTestDataFetcher() {
return new VertxDataFetcher<>((env, future) -> future.complete(doTest()));
}
private Publisher<String> doTest() {
AtomicReference<Subscription> ar = new AtomicReference<>();
Observable<String> obs = Observable.just("Hello");
Publisher<String> pub = obs.toFlowable(BackpressureStrategy.BUFFER);
pub.subscribe(new Subscriber<String>() {
#Override
public void onSubscribe(Subscription s) {
System.out.println("SUBSCRIBE");
ar.set(s);
s.request(1);
}
#Override
public void onNext(String s) {
System.out.println("NEXT="+s);
ar.get().request(1);
}
#Override
public void onError(Throwable t) {
System.out.println("ERROR");
}
#Override
public void onComplete(){
System.out.println("COMPLETE");
}
}
return pub;
}
If I run the subscription using GraphiQL and look on my vert.x servers console, the output on the console is:
SUBSCRIBE
NEXT=Hello
COMPLETE
The GraphiQL output window says "Internal Server Error" and is sent a 500 error code from the server
If I modify the DataFetcher to exactly what is shown at the bottom of the first link, I also receive "Internal Server Error".
private DataFetcher<Publisher<String>> getTestDataFetcher() {
return env -> doTest();
}
I do not see any stack traces for the 500 error in the vertx console. So maybe this is a bug?
Sidenote - If I try using a CompletionStage as shown below (based off the bottom of the 2nd link) I get an error message saying 'You data fetcher must return a publisher of events when using graphql subscriptions'
private DataFetcher<CompletionStage<String>> getTestDataFetcher() {
Single<String> single = Single.create(emitter -> {
new Thread(()-> {
try {
emitter.onSuccess("Hello");
} catch(Exception e) {
emitter.onError(e);
}
}).start();
)};
return environment -> single.to(SingleInterop.get());
}
I have used the following sources as references to get this far:
https://www.graphql-java.com/documentation/v9/subscriptions/
https://vertx.io/docs/vertx-web-graphql/java/
I want to implement a very simple Java Telegram Client, which is capable of sending and receiving messages and store the sessions across multiple starts. I already managed to authenticate and receive messages
api = new TelegramApi(apiState, new AppInfo(API_ID, "console", "1", "1", "en"), new ApiCallback() {
#Override
public void onAuthCancelled(TelegramApi api) {
Log.d(TAG, "-----------------CANCELLED----------------");
Log.d(TAG, api.getApiContext().toString());
}
#Override
public void onUpdatesInvalidated(TelegramApi api) {
Log.d(TAG, "-----------------INVALIDATED----------------");
Log.d(TAG, api.getApiContext().toString());
}
#Override
public void onUpdate(TLAbsUpdates tlAbsUpdates) {
Log.d(TAG, "-----------------UPDATE----------------");
Log.d(TAG, tlAbsUpdates.toString());
if (tlAbsUpdates instanceof TLUpdateShortMessage) {
Log.d(TAG, "-----------------UPDATE CHAT MESSAGE----------------");
int senderId = ((TLUpdateShortMessage) tlAbsUpdates).getUserId();
Log.d(TAG, "Message from " + senderId);
String message = ((TLUpdateShortMessage) tlAbsUpdates).getMessage();
Log.d(TAG, message);
activity.appendMessage(TAG, message);
}
}
});
api.switchToDc(2);
TLConfig config = null;
try {
config = api.doRpcCallNonAuth(new TLRequestHelpGetConfig());
} catch (TimeoutException | IOException e) {
e.printStackTrace();
}
apiState.updateSettings(config);
However, I struggle to send messages to another user. For the beginning, it would be enough if I could send a message back to the user, who sent me a message before (by retrieving the senderId, as you can see in the onUpdate method before). However, if someone could also help me with retrieving the ids of my saved contacts, it would be perfect.
Furthermore, I want to store the sessions accross multiple startups, since I get a FLOOD_WAIT error (420), if I test my code to often.
For this I used https://github.com/rubenlagus/TelegramApi/blob/51713e9b6eb9e0ae0d4bbbe3d4deffff9b7f01e4/src/main/java/org/telegram/bot/kernel/engine/MemoryApiState.java and its used classes (e.g. TLPersistence), which stores and loads the ApiState. However, apparently it does not store the signin status, since I always have to authenticate my number every time I update the code.
By the way, I am using Api layer 66 (https://github.com/rubenlagus/TelegramApi/releases).
UPDATE 1:
Problems with sending messages solved myself:
private void sendMessageToUser(int userId, String message) {
TLInputPeerUser peer = new TLInputPeerUser();
peer.setUserId(userId);
TLRequestMessagesSendMessage messageRequest = new TLRequestMessagesSendMessage();
messageRequest.setFlags(0);
messageRequest.setPeer(peer);
messageRequest.setRandomId(new SecureRandom().nextLong());
messageRequest.setMessage(message);
api.doRpcCallNonAuth(messageRequest, 1500, new RpcCallback<TLAbsUpdates>() {
#Override
public void onResult(TLAbsUpdates tlAbsUpdates) {
Log.d(TAG, "-----------------------MESSAGE SENT-----------------------");
}
#Override
public void onError(int i, String s) {
Log.d(TAG, "-----------------------MESSAGE SENT ERROR-----------------------");
Log.d(TAG, String.valueOf(i));
if(s != null) {
Log.d(TAG, s);
}
}
});
}
However, now I am stuck at finding the userIds of my contacts.
After first update this is left:
Saving the session state (and signin state)
Find userIds of contacts
Update 2:
I managed to fetch the users, with which there are already dialogs. This is enough for my use case, however, loading all contacts would be perfect. This is how to load users from existing dialogs:
private int getUserId(String phone) throws InterruptedException {
TLRequestMessagesGetDialogs dialogs = new TLRequestMessagesGetDialogs();
dialogs.setOffsetId(0);
dialogs.setLimit(20);
dialogs.setOffsetPeer(new TLInputPeerUser());
CountDownLatch latch = new CountDownLatch(1);
api.doRpcCallNonAuth(dialogs, 1500, new RpcCallback<TLAbsDialogs>() {
#Override
public void onResult(TLAbsDialogs tlAbsDialogs) {
Log.d(TAG, "----------------------getUsers--------------------");
for(TLAbsUser absUser : ((TLDialogs) tlAbsDialogs).getUsers()) {
users.add((TLUser) absUser);
}
latch.countDown();
}
#Override
public void onError(int i, String s) {
Log.d(TAG, "----------------------getUsers ERROR--------------------");
latch.countDown();
}
});
latch.await();
for(TLUser user : users) {
if(user.getPhone().equals(phone)) {
return user.getId();
}
}
return 0;
}
After second update this is left:
Saving the session state (and signin state)
Get user ids from contacts instead of dialogs
i used the java telegram api to communicate with telegram core api in windows intellij idea
https://github.com/ex3ndr/telegram-api
But the app is facing Timeout error in line TLConfig config = api.doRpcCall(new TLRequestHelpGetConfig());Full source code:
AppInfo appinfo=new AppInfo(45687, "Myapp", "154", "587","en");
TLRequestAuthCheckPhone checkRequest = new TLRequestAuthCheckPhone("96521452365");
MyApiStorage state=new MyApiStorage();
TelegramApi api = new TelegramApi(state, appinfo, new ApiCallback()
{
public void onApiDies(TelegramApi api) {
// When auth key or user authorization dies
}
#Override
public void onUpdatesInvalidated(TelegramApi api) {
System.out.print("############################### onUpdatesInvalidated");
// When api engine expects that update sequence might be broken
}
#Override
public void onAuthCancelled(TelegramApi ta) {
System.out.print("############################### onAuthCancelled");
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void onUpdate(TLAbsUpdates updates) {
System.out.print("############################### onUpdate");
System.out.println("user Id ::::"+((TLUpdateShortMessage) updates).getFromId());
}
});
api.switchToDc(1);
TLConfig config = api.doRpcCall(new TLRequestHelpGetConfig());
System.out.print("############################### config" + config.getTestMode());
state.updateSettings(config);
api.doRpcCall(checkRequest, new RpcCallbackEx<TLCheckedPhone>() {
public void onConfirmed() {
System.out.print("############################### onConfirmed");
}
public void onResult(TLCheckedPhone result) {
boolean invited = result.getPhoneInvited();
boolean registered = result.getPhoneRegistered();
System.out.print("############################### onResult" + registered);
// TODO process response further
}
public void onError(int errorCode, String message) {
System.out.print("############################### onError" + message);
}
});
can someone help me
Your timeout might happen for several reasons:
1. You are using
api.doRpcCall(new TLRequestHelpGetConfig());
In the TelegramApi class this translates into
return this.doRpcCall(method, timeout, 0);
0 there stands for DC. If your DC is different you will timeout
2. There were suggestions in other places to use doRpcCallSide instead and it worked for some and not for others. The reason is it translates into
return this.doRpcCall(method, 15000, this.primaryDc, true);
where true stands authRequired.
3. If you want to do this without authorization then use api.doRpcCallNonAuth
I'm writing a project in GWT over GAE with SmartGWT.
I've got a DB with object, each having a "father" object and "sons", and I'm using a TreeGrid to represent them. I already have a GWT-RPC service that gets the sons of a given node.
What I need now is to somehow extend the DataSource class s.t when a tree node is opened, I will be able to use my own service to go and fetch it's sons - and then return them as something the TreeGrid can work with.
I know I'm suppose to override transformRequest and transformResponse, but I have no idea how. Any code sample / explanation will be greatly appreciated!
This is what I have so far - not sure it's even remotely correct:
budgetTree.setDataSource(new DataSource() {
#Override
protected Object transformRequest(final DSRequest dsRequest) {
expensesService.getExpensesByYear(2008,
new AsyncCallback<ExpenseRecord[]>() {
#Override
public void onSuccess(ExpenseRecord[] result) {
System.out.println("Returned " + result.length + " expense record ");
dsRequest.setAttribute("dsResult", result);
}
#Override
public void onFailure(Throwable caught) {
System.out.println("Failed to run query");
}
});
return dsRequest;
}
#Override
protected void transformResponse(DSResponse response, DSRequest request,
Object data) {
Record[] recs = request.getAttributeAsRecordArray("dsResult");
response.setData(recs);
super.transformResponse(response, request, data);
}
});
Since you are performing the actual request yourself , you first need to look at
setDataProtocol(DSProtocol.CLIENTCUSTOM);
Then in both onSuccess and onFailure you would need to call processResponse() which will call transformResponse()
public class MyDatasource extends DataSource{
public MyDatasource(){
setDataProtocol(DSProtocol.CLIENTCUSTOM)
}
#Override
protected Object transformRequest(final DSRequest dsRequest) {
expensesService.getExpensesByYear(2008,
new AsyncCallback<ExpenseRecord[]>() {
#Override
public void onSuccess(ExpenseRecord[] result) {
DSResponse response = new DSResponse();
System.out.println("Returned " + result.length + " expense record ");
dsRequest.setAttribute("dsResult", result);
Record[] recs = request.getAttributeAsRecordArray("dsResult");
response.setData(recs);
processResponse(dsRequest.getRequestId(), dsResponse);
}
#Override
public void onFailure(Throwable caught) {
DSResponse response = new DSResponse();
System.out.println("Failed to run query");
processResponse(dsRequest.getRequestId(), dsResponse);
}
});
return dsRequest;
}
}