Stream Closed error in twitter4j how to solve - java

it says Stream Closed error
public class StreamAPI {
public static void main(String[] args) {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true);
cb.setOAuthConsumerKey("xxxx");
cb.setOAuthConsumerSecret("xxx");
cb.setOAuthAccessToken("xx-xx");
cb.setOAuthAccessTokenSecret("xxx");
cb.setUseSSL(true);
cb.setUserStreamRepliesAllEnabled(true);
TwitterStream twitterStream = new TwitterStreamFactory(cb.build()).getInstance();
AccessToken accestoken = new AccessToken("xx-xx", "xxx");
twitterStream.setOAuthAccessToken(accestoken);
StatusListener listener = new StatusListener() {
public void onStatus(Status status) {
System.out.println("#" + status.getUser().getScreenName() + " - " + status.getText());
}
public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {
System.out.println("Got a status deletion notice id:" + statusDeletionNotice.getStatusId());
}
public void onTrackLimitationNotice(int numberOfLimitedStatuses) {
System.out.println("Got track limitation notice:" + numberOfLimitedStatuses);
}
public void onScrubGeo(long userId, long upToStatusId) {
System.out.println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId);
}
#Override
public void onStallWarning(StallWarning stallWarning) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void onException(Exception ex) {
ex.printStackTrace();
}
};
FilterQuery fq = new FilterQuery();
String keywords[] = {"France", "Germany"};
fq.track(keywords);
twitterStream.addListener(listener);
twitterStream.filter(fq);
}
}
i am getting error
Stream closed.
Relevant discussions can be found on the Internet at:
http://www.google.co.jp/search?q=a8fd061d or
http://www.google.co.jp/search?q=00070a0c
TwitterException{exceptionCode=[a8fd061d-00070a0c a8fd061d-0007099d], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=3.0.3}
at twitter4j.StatusStreamBase.handleNextElement(StatusStreamBase.java:199)
at twitter4j.StatusStreamImpl.next(StatusStreamImpl.java:57)
at twitter4j.TwitterStreamImpl$TwitterStreamConsumer.run(TwitterStreamImpl.java:478)
Caused by: java.io.IOException: the end of the stream has been reached
at twitter4j.StatusStreamBase.handleNextElement(StatusStreamBase.java:88)
... 2 more
But the same configuration works for TwitterAPI

Twitter gives the following reasons why you may be disconnected:
A client establishes too many connections with the same credentials. When this occurs, the oldest connection will be terminated. This means
you have to be careful not to run two reconnecting clients in parallel
with the same credentials, or else they will take turns disconnecting
each other.
A client stops reading data suddenly. If the rate of Tweets being read off of the stream drops suddenly, the connection will be closed.
A client reads data too slowly. Every streaming connection is backed
by a queue of messages to be sent to the client. If this queue grows
too large over time, the connection will be closed.
A streaming server is restarted. This is usually related to a code deploy and is not very frequent.
Twitter's network configuration changes. These events are extremely rare, and would represent load balancer restarts or network
reconfigurations, for example.
You should receive information on why you were disconnected, but not always:
Streams may be shut down for a variety of reasons. The streaming API will attempt to deliver a message indicating why a stream was closed. Note that if the disconnect was due to network issues or a client reading too slowly, it is possible that this message will not be received.
My thought would be that perhaps you're not reading data quickly enough - although I can't say for certain. Try implementing onStallWarning to see if you're getting any stall warnings, e.g.:
#Override
public void onStallWarning(StallWarning stallWarning) {
System.out.println(stallWarning);
}

Related

Connect to pusher in android app, multiple or once?

In my app (streaming series, movies) I have a section for users that can set Reminder for the series or movies. And I implement Pusher to receive server message for reminding data.
Is it true that I connect to channel for each item in the reminder list?? or I should connect to the pusher once and in the pusher event get related series/ movies message?(Server-side implemented pusher for each reminder list items, should we change server-side implementation or I can connect to pusher for each items? )
This is my Implementation for pusher:
public Pusher getPusher() throws Exception {
if (pusher == null) {
HttpAuthorizer auth = new HttpAuthorizer(BuildConfig.PUSHER);
HashMap<String, String> authHeader = new HashMap<>();
authHeader.put("Authorization", SharedPref.INSTANCE.read(AUTH_TOKEN, ""));
auth.setHeaders(authHeader);
PusherOptions option = new PusherOptions();
option.setCluster(BuildConfig.PUSHER_CLUSTER);
option.setAuthorizer(auth);
pusher = new Pusher(BuildConfig.PUSHER_KEY, option);
pusher.subscribePrivate("private-app_ch." + serialId, new PrivateChannelEventListener() {
#Override
public void onAuthenticationFailure(String s, Exception e) {
Timber.i("pusher onAuthenticationFailure " + e.getMessage());
}
#Override
public void onSubscriptionSucceeded(String s) {
Timber.i("pusher onSubscriptionSucceeded: " + s);
}
#Override
public void onEvent(String s, String s1, String result) {
Timber.i("pusher onEvent" + s + ":" + s1);
Timber.i("pusher onEvent" + result);
}
}, "App\\Events\\AppBroadcastEvent");
}
return pusher;
}
The best practice for this would be to maintain one connection to Channels but make a subscription for each item in the reminder list.
So you would call pusher.subscribePrivate for each item in the reminder list and then on the server side publish to each individual Channel when a reminder needs to be sent.
For example if a user wanted to be reminded about 'Stranger Things' and 'Orange is the new black' you would subscribe to both:
pusher.subscribePrivate("private-app_ch.strangerthings"
and
pusher.subscribePrivate("private-app_ch.orangeisthenewblack"
Your server would then publish reminders about 'Stranger Things' to the Stranger things channel and OISTNB to the OISTNB channel and so on.
This way only relevant updates are sent to the client (server-side filtering). If you only subscribe to one channel the client will get messages they may not want updates about and you would have to filter these out on the client side.
This is also explained here: https://support.pusher.com/hc/en-us/articles/360025398514-Should-i-subscribe-to-lots-of-Channels-
One additional point that is worth considering is that Channels will only maintain an active connection when the app is open. The connection will be closed when the app is backgrounded/closed. This means for reminders to be sent the user would always have to be in your app. You may want to consider also sending push notifications when the app is closed so the user does not miss reminders.

Netty Correlating Request and Responses

I want to write a proxy for a TCP binary protocol. I’m using the HexDump example in Netty’s repo as a guide.
https://github.com/netty/netty/tree/4.1/example/src/main/java/io/netty/example/proxy
This works fine. But I sometimes want to modify the response based on the original request.
Looking around it seems that using the inbound channels AttributeMap could be the place to store such request details. (Some more details below)
io.netty.util.AttributeMap
But while it sort of works sometimes one request overwrites the details of another request.
This makes sense, Netty is asynchronous and you can’t really guarantee when somethings going to happen.
So I was wondering how can I reliably correlate each request with is response. Note I can’t
change the protocol, this might have been one way to pass details between request and response.
Thanks for your insight.
HexDumpFrontendHandler
#Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws InterruptedException {
…
ctx.channel().attr(utils.REQUEST_ATTRIBUTE).set(requestDetails);
…
}
#Override
public void channelActive(ChannelHandlerContext ctx) {
final Channel inboundChannel = ctx.channel();
// Start the connection attempt.
Bootstrap b = new Bootstrap();
b.group(inboundChannel.eventLoop())
.channel(ctx.channel().getClass())
.handler(new HexDumpBackendHandler(inboundChannel))
.option(ChannelOption.AUTO_READ, false);
ChannelFuture f = b.connect(remoteHost, remotePort);
outboundChannel = f.channel();
f.addListener((ChannelFutureListener) future -> {
if (future.isSuccess()) {
// connection complete start to read first data
inboundChannel.read();
} else {
// Close the connection if the connection attempt has failed.
inboundChannel.close();
}
});
}
HexDumpBackendHandler
#Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) {
…
RequestDetails requestDetails = inboundChannel.attr(utils.REQUEST_ATTRIBUTE).getAndRemove();
…
}
My solution (work around?) to this was the following. The protocol I was working with couldn't guarantee a unique identifier per request globally but it did uniquely identify request's within a tcp connection.
So the following combination allowed me to create a ConcurrentHashMap with the following as the key
host + ephemeral port + identifier local to the connection
This work for my case. I'm sure their other ways to solve it within the Netty framework itself

Handle android server communication after errors

My android app is using a http connection to send data to a server. If the server received the data the app marks the data as successfully transmitted in its own database.
Sometimes external problems may occur, so that the transmission cannot be completed. The app should try sending the data again later.
What is a good possibility to make sure, that the data reaches the server? I only can think of a service, which checks periodically for not transmitted data, but I don't like this approach.
Heres some psuedo code..
1.Create a AcknowledgementManager which waits for acknowledgement of each request.
2.The acknowledgement manager posts a runnable which will run after TIME_OUT interval.
public void startListeningForTimeOut(CallContext callContext) {
TimeOutRunnable timeOutRunnable = new TimeOutRunnable(callContext);
mMapRunnables.put(callContext, timeOutRunnable);
mHandler.postDelayed(timeOutRunnable, TIMEOUT_DURATION);
Slog.d(TAG,
"started listening for timeout for token: " + callContext + " at: "
+ System.currentTimeMillis());
}
3.1 If the AcknowledgementManager receives acknowledgement for the data it cancels the runnable for that data and make necessary updates in database.
public void stopListeningForTimeOut(CallContext callContext) {
mHandler.removeCallbacks(mMapRunnables.get(callContext));
mMapRunnables.remove(callContext);
Slog.d(TAG,
"stopped listening for timeout for token: " + callContext + " at: "
+ System.currentTimeMillis());
}
3.2 If the acknowledgement is not received the runnable raises a "timeout" to the AcknowledgementManager.The AcknowledgementManager retries sending data.
public class TimeOutRunnable implements Runnable {
private static final String TAG = "TimeOutThread rupesh";
CallContext mToken;
// String mCallback;
public TimeOutRunnable(CallContext callContext) {
mToken = callContext;
// mCallback = callbackTBD;
// FIXME send proper callback class
}
#Override
public void run() {
Slog.d(TAG, "timeout occured for data id: " + mToken + " at: " + System.currentTimeMillis());
mToken.onTimeOutOccurred();
}
}
Please note:
1.Before syncing the data please make the entry of data in db so that the data does not get lost between app restart.
2.Before you start the syncing process query the db to get the data which is not being transmitted.Based on the data size,make sure you keep the data to be transmitted in memory to avoid hitting the db everytime.
3.Once you get acknowledgement for a data item,make necessary changes for that entry in db.
4.You can also have 'retry' flag in db so that you keep track of no of retries.

How to detect an error while sending a chat using Smack

I'm using smack to send a chat message. While testing i figured out that, when the network is unavilable, the API does not throw any exceptions.
my code :
Chat chat = connection.getChatManager().createChat(
"abc#gmail.com", new MessageListener() {
#Override
public void processMessage(Chat arg0, Message arg1) {
System.out.println(arg1.getFrom() + " says " + arg1.getBody());
}
});
// I Put a break point here and deliberately disable the network.
// But the following line is not throwing the XMPPException
chat.sendMessage("smack says hi.."); /* Send the message  */
Should i add any listeners to capture the exception?
You won't get an exception since it is an asynchronous call. If you want to know if the connection has been dropped, you will have to register a ConnectionListener with the Connection.

Does Smack work well in Java EE

Does Smack function properly in Java EE?? I am having issues with presence.
I get the credentials from the login form via doPost method..I can able to successfully authenticate as well as connection.getRoster() also works.Next I want to show only users who are online so when I get the presence of user,presence object stores default value "unavailable" for all users even when they are available!!
The whole chat app works without flaw in a normal java class without any change..
String userName = request.getParameter("username");
String password = request.getParameter("password");
HttpSession session=request.getSession();
session.setAttribute("username", userName);
SmackAPIGtalkServlet gtalk = new SmackAPIGtalkServlet();
ConnectionConfiguration config = new ConnectionConfiguration(
"talk.google.com", 5222, "gmail.com");
connection = new XMPPConnection(config);
config.setSASLAuthenticationEnabled(false);
try {
connection.connect();
} catch (XMPPException e) {
e.printStackTrace();
}
try {
connection.login(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
System.out.println(connection.isAuthenticated());
boolean status = connection.isAuthenticated();
if (status == true) {
gtalk.displayOnlineBuddyList();
response.sendRedirect("Roster.jsp");
}
else
{
response.sendRedirect("Failed.jsp");
}
}
public void displayOnlineBuddyList() {
Roster roster = connection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
int count1 = 0;
int count2 = 0;
for (RosterEntry r : entries) {
Presence presence = roster.getPresence(r.getUser());
if (presence.getType() == Presence.Type.unavailable) {
// System.out.println(user + "is offline");
count1++;
} else {
System.out.println(name+user + "is online");
count2++;
}
}
roster.addRosterListener(new RosterListener() {
// Ignored events public void entriesAdded(Collection<String>
// addresses) {}
public void entriesDeleted(Collection<String> addresses) {
}
public void entriesUpdated(Collection<String> addresses) {
}
public void presenceChanged(Presence presence) {
System.out.println("Presence changed: " + presence.getFrom()
+ " " + presence);
}
#Override
public void entriesAdded(Collection<String> arg0) {
// TODO Auto-generated method stub
}
});
}
I am stuck with this and not able to get the code working with servlets..Can anyone help me out??
Will Smack work inside of Java EE, yes and no.
Smack will work inside of a web container, but since it creates its own threads it will NOT work inside of an EJB container. So it will work depending on where you are running it.
To understand some of your issues, you have to understand that the lifecycle of your objects in a servlet is tied to the request/response cycle of each request. This is not the same as a standard java app where the objects will typically live as long as you need them to, since you control their lifecycle.
For example, in the code you have shown, you create the connection for each request (I assume, since not all the code is shown). Therefore registering listeners against that connection will be pointless since it will pass out of scope as soon as you leave the method, and eventually get garbage collected. You will have to maintain the connections outside of the scope of the servlet requests for this to work, otherwise you will be opening and closing connections for each request.
XMPP is completely asynchronous by nature whereas servlet requests are synchronous. You have to put some effort in to making them work together, so don't expect code that works in a standalone app to simply work in this environment.
You have to implement the RosterListener interface in which you have to override the presenceChanged method in that you can get the presence of the users.
It works for me.
When you are getting the rosters of GTalk all will have status as unavailable.
But after sometime their presence changes and the presence can be get from the presenceChanged method in the RosterListner but for that you have to implement the RosterListener's presenceChnaged method.
And ya it works well in Java EE, Android as well as WAP.
Does Smack function properly in Java EE?? I am having issues with presence. I get the credentials from the login form via doPost method..I can able to successfully authenticate as well as connection.getRoster() also works.Next I want to show only users who are online so when I get the presence of user,presence object stores default value "unavailable" for all users even when they are available!! here my code
<%
Roster rst = roster;
rst.addRosterListener(new RosterListener() {
public void entriesAdded(final Collection args) {}
public void entriesDeleted(final Collection<String> addresses) {}
public void entriesUpdated(final Collection<String> addresses) {}
public void presenceChanged(final Presence presence) {
final Presence prsence1 = presence;
prsenceChanged(prsence1);
if (prsence1.isAvailable()) {
System.out.println("Is Available: " + presence.isAvailable());
}
}
});
%>
<%!void prsenceChanged(Presence presence){ if(null != presence){%>
<script language="javascript">
alert("hai");
</script>

Categories