チャット機能を実装している Android アプリケーションに取り組んでいます。Cometd を使用しているため、チャットは非常に高速ですが、何らかの理由で Cometd が代替メッセージを送信しています。メッセージ 1 を送信する場合、メッセージ 2 を送信せず、メッセージ 3 を送信する、というように続きます。これは非常に奇妙な動作であり、エラーがないため問題を特定するのは困難です。
システム ログを追加して、onClick メソッドが呼び出されているかどうか、およびメッセージを送信する内部のループを確認しました。また、サーバー側のコードに system.out を追加したところ、代替メッセージのみが受信されます。これにより、Cometd が何らかの理由ですべての代替メッセージを送信していないという結論に至りました。どんな助けでもいいでしょう。ありがとうございました。
PUSH サービスは、ConsoleChatClient.java でインスタンス化された Cometd によって提供されることに注意してください。
コード :
public class ChatMessagesActivity extends ApplicationDrawerLoader {
HttpClient httpClient;
ConsoleChatClient consoleChatClient;
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, ConsoleChatClient.class);
bindService(intent, mConnection, Context.BIND_IMPORTANT);
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
ConsoleChatClient.LocalBinder binder = (ConsoleChatClient.LocalBinder) service;
consoleChatClient = binder.getService();
mBound = true;
onConsoleChatClientReady();
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
private void onConsoleChatClientReady() {
httpClient = consoleChatClient.httpClient;
subscribeFlag = true;
Bundle extras = getIntent().getExtras();
if (extras != null) {
groupAccountId = extras.getLong("groupid");
conversationId = extras.getInt("conversationid");
}
if (conversationId != 0) {
consoleChatClient.bayeuxClient.getChannel("/person/" + conversationId).subscribe(chatListener);
}
if (groupAccountId != 0) {
consoleChatClient.bayeuxClient.getChannel("/chat/" + groupAccountId).subscribe(chatListener);
}
}
sendMessageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// method below sends the message, and it does so for every //alternate message precisely.
Log.d("We","groupmessage");
Map<String, Object> outputData = new HashMap<>();
outputData.put("name", typeMessageField.getText().toString());
outputData.put("timestamp", new Timestamp(System.currentTimeMillis()));
outputData.put("type", false);
consoleChatClient.bayeuxClient.getChannel("/service/chat/" + String.valueOf(groupAccountId)).publish(outputData);
}
ConsoleChatClient :
public class ConsoleChatClient extends Service {
private final IBinder mBinder = new LocalBinder();
BayeuxClient bayeuxClient = StaticRestTemplate.getClient();
HttpClient httpClient = StaticRestTemplate.getHttpClient();
String defaultURL = StaticRestTemplate.baseURL + "/cometd";
public class LocalBinder extends Binder {
ConsoleChatClient getService() {
// Return this instance of LocalService so clients can call public methods
return ConsoleChatClient.this;
}
}
private void connectionEstablished() {
System.err.printf("system: Connection to Server Opened%n");
}
private void connectionClosed() {
System.err.printf("system: Connection to Server Closed%n");
}
private void connectionBroken() {
System.err.printf("system: Connection to Server Broken%n");
}
@Override
public void onCreate() {
super.onCreate();
performConnection();
}
@Override
public IBinder onBind(Intent intent) {
performConnection();
return mBinder;
}
private void performConnection() {
try {
httpClient.start();
ClientTransport clientTransport = new LongPollingTransport(null, httpClient);
bayeuxClient = new BayeuxClient(defaultURL, clientTransport);
// Below for use with Spring-Security post-login.
bayeuxClient.putCookie(new HttpCookie("JSESSIONID", StaticRestTemplate.getJsessionid()));
bayeuxClient.getChannel(Channel.META_HANDSHAKE).addListener(new InitializerListener());
bayeuxClient.getChannel(Channel.META_CONNECT).addListener(new ConnectionListener());
bayeuxClient.handshake();
StaticRestTemplate.setClient(bayeuxClient);
StaticRestTemplate.setHttpClient(httpClient);
boolean success = bayeuxClient.waitFor(2000, BayeuxClient.State.CONNECTED);
if (!success) {
System.err.printf("Could not handshake with server at %s%n", defaultURL);
}else {
System.err.printf("Handhskare complete");
}
} catch (Exception ignored) {}
}
private class InitializerListener implements ClientSessionChannel.MessageListener {
@Override
public void onMessage(ClientSessionChannel channel, Message message) {
if (message.isSuccessful()) {
System.out.println("Message successful");
}
}
}
private class ConnectionListener implements ClientSessionChannel.MessageListener {
private boolean wasConnected;
private boolean connected;
public void onMessage(ClientSessionChannel channel, Message message) {
if (bayeuxClient.isDisconnected()) {
connected = false;
connectionClosed();
return;
}
wasConnected = connected;
connected = message.isSuccessful();
if (!wasConnected && connected) {
connectionEstablished();
} else if (wasConnected && !connected) {
connectionBroken();
}
}
}
}
public class ConsoleChatClient extends Service {
private final IBinder mBinder = new LocalBinder();
BayeuxClient bayeuxClient = StaticRestTemplate.getClient();
HttpClient httpClient = StaticRestTemplate.getHttpClient();
String defaultURL = StaticRestTemplate.baseURL + "/cometd";
public class LocalBinder extends Binder {
ConsoleChatClient getService() {
// Return this instance of LocalService so clients can call public methods
return ConsoleChatClient.this;
}
}
private void connectionEstablished() {
System.err.printf("system: Connection to Server Opened%n");
}
private void connectionClosed() {
System.err.printf("system: Connection to Server Closed%n");
}
private void connectionBroken() {
System.err.printf("system: Connection to Server Broken%n");
}
@Override
public void onCreate() {
super.onCreate();
performConnection();
}
@Override
public IBinder onBind(Intent intent) {
performConnection();
return mBinder;
}
private void performConnection() {
try {
httpClient.start();
ClientTransport clientTransport = new LongPollingTransport(null, httpClient);
bayeuxClient = new BayeuxClient(defaultURL, clientTransport);
// Below for use with Spring-Security post-login.
bayeuxClient.putCookie(new HttpCookie("JSESSIONID", StaticRestTemplate.getJsessionid()));
bayeuxClient.getChannel(Channel.META_HANDSHAKE).addListener(new InitializerListener());
bayeuxClient.getChannel(Channel.META_CONNECT).addListener(new ConnectionListener());
bayeuxClient.handshake();
StaticRestTemplate.setClient(bayeuxClient);
StaticRestTemplate.setHttpClient(httpClient);
boolean success = bayeuxClient.waitFor(2000, BayeuxClient.State.CONNECTED);
if (!success) {
System.err.printf("Could not handshake with server at %s%n", defaultURL);
}else {
System.err.printf("Handhskare complete");
}
} catch (Exception ignored) {}
}
private class InitializerListener implements ClientSessionChannel.MessageListener {
@Override
public void onMessage(ClientSessionChannel channel, Message message) {
if (message.isSuccessful()) {
System.out.println("Message successful");
}
}
}
private class ConnectionListener implements ClientSessionChannel.MessageListener {
private boolean wasConnected;
private boolean connected;
public void onMessage(ClientSessionChannel channel, Message message) {
if (bayeuxClient.isDisconnected()) {
connected = false;
connectionClosed();
return;
}
wasConnected = connected;
connected = message.isSuccessful();
if (!wasConnected && connected) {
connectionEstablished();
} else if (wasConnected && !connected) {
connectionBroken();
}
}
}
}
カウンター付きコード: 0 で初期化されたカウンター。
Map<String, Object> outputData = new HashMap<>();
outputData.put("name", typeMessageField.getText().toString());
outputData.put("timestamp", new Timestamp(System.currentTimeMillis()));
outputData.put("type", "false");
outputData.put("counter",counter);
counter++;
try {
if(consoleChatClient.httpClient.isStarted()) {
consoleChatClient.bayeuxClient.getChannel("/service/chat/" + String.valueOf(groupAccountId)).publish(outputData);
Log.d("Android, counter",String.valueOf(counter));
}else {
consoleChatClient.httpClient.start();
Log.d("Client","not started");
}
}catch (Exception e){
e.printStackTrace();
}
カウンターのサーバー側印刷:
@Listener("/service/chat/{id}")
public void processHello(ServerSession remote, ServerMessage message, @Param("id") String id) {
System.out.println("I was called"+message.toString());
// Other code
}
Android のログ:
04-04 10:30:11.465 2047-2271/mycompany.app I/System.out: Message successful
04-04 10:30:11.485 2047-2265/mycompany.app W/System.err: system: Connection to Server Opened
04-04 10:30:11.585 2047-2266/mycompany.app I/System.out: Message successful
04-04 10:30:11.697 2047-2270/mycompany.app W/System.err: Handhskare completesystem: Connection to Server Opened
04-04 10:30:11.720 2047-2047/mycompany.app I/Choreographer: Skipped 41 frames! The application may be doing too much work on its main thread.
04-04 10:30:13.738 2047-2047/mycompany.app W/Settings: Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.
04-04 10:30:19.394 2047-2047/mycompany.app D/Android, counter: 1
04-04 10:30:29.557 2047-2047/mycompany.app D/Android, counter: 2
04-04 10:30:51.787 2047-2047/mycompany.app D/Android, counter: 3
04-04 10:31:05.414 2047-2047/mycompany.app D/Android, counter: 4
04-04 10:31:15.590 2047-2047/mycompany.app D/Android, counter: 5
04-04 10:31:26.513 2047-2047/mycompany.app D/Android, counter: 6
04-04 10:31:32.510 2047-2047/mycompany.app D/Android, counter: 7
04-04 10:31:43.192 2047-2047/mycompany.app D/Android, counter: 8
04-04 10:31:49.566 2047-2047/mycompany.app D/Android, counter: 9
サーバー側のログ:
I was called{clientId=412fqdbm458ip31je6r676za42t, data={name=hello, counter=1, type=false, timestamp=2016-04-04 10:30:29.547}, channel=/service/chat/5250, id=9}
Authenticated user is AKSHAY
I was called{clientId=412fqdbm458ip31je6r676za42t, data={name=wassup, counter=2, type=false, timestamp=2016-04-04 10:30:51.78}, channel=/service/chat/5250, id=12}
Authenticated user is AKSHAY
I was called{clientId=412fqdbm458ip31je6r676za42t, data={name=yoyo, counter=4, type=false, timestamp=2016-04-04 10:31:15.583}, channel=/service/chat/5250, id=16}
Authenticated user is AKSHAY
I was called{clientId=412fqdbm458ip31je6r676za42t, data={name=hhhh, counter=6, type=false, timestamp=2016-04-04 10:31:32.501}, channel=/service/chat/5250, id=18}
Authenticated user is AKSHAY
I was called{clientId=412fqdbm458ip31je6r676za42t, data={name=hhhhh, counter=8, type=false, timestamp=2016-04-04 10:31:49.557}, channel=/service/chat/5250, id=22}
Authenticated user is AKSHAY
ログ画像: