4

チャット機能を実装している 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

ログ画像:

ここに画像の説明を入力

ここに画像の説明を入力

ここに画像の説明を入力

4

0 に答える 0