gpt4 book ai didi

java - 安卓 : Keep httpclient running in background and communicate with activity when message recieved by httpclient

转载 作者:行者123 更新时间:2023-12-01 16:54:37 25 4
gpt4 key购买 nike

抱歉标题太长,但我不知道该怎么做。我正在开发一个 Android 项目,在该项目中我尝试使用名为 Cometd 的 PUSH 框架。 。现在Cometd使用Bayuex API/规范来实现PUSH服务。

当您考虑普通网站部分(用户登录或服务器端可扩展异步应用程序)时,Cometd 的工作效果简直棒极了,没有什么可提示的。我们面临的问题是在应用程序方面。没有可用的支持或文档。

经过一番努力,我能够编写代码在 Android 应用程序中使用 Cometd,不幸的是它有错误且不稳定。我将描述我如何构建它的结构,描述问题并显示代码。

有 2 个主要的 Activity 类:ConversationActivityChatMessagesActivity。在 ConversationActivity 中,我启动一个 httpclient 并通过执行握手连接到 PUSH 服务。

在同一个类中,有一个 ClientSessionChannel 监听器,它不断监听新消息。在 ConversationActivity 类中,我从服务器数据库中检索登录用户的所有对话。完成后,用户可以决定他/她想与谁聊天。

现在,当点击对话时,我会在另一个 Activity 中打开这两个用户的聊天消息。

现在,不要忘记每条新消息都会到达 ConversationActivity 中的 ClientSessionChannel Listener 中,这就是为什么我必须维护 ConversationActivity 和 ChatMessagesActivity 之间的通信链接的原因,这会导致各种不稳定。

现在,我想做的是将监听器和 httpclient 推送到另一个线程/类/背景等中。完成后,如何保持聊天消息之间的开放通信已打开,因此消息会更新。我希望问题已经清楚了。我现在将发布代码。请看一下:

public class ConversationActivity extends ApplicationDrawerLoader {

static Context context;
List<PrivateChannel> privateChannelList = new ArrayList<>();

List<Long> groupAccountList = new ArrayList<>();

List<String> pushPrivateChannelList = new ArrayList<>();

ListView conversationsList;

ConversationAdapter conversationAdapter;

protected static volatile BayeuxClient client;
private ChatListener chatListener = new ChatListener();

HttpClient httpClient = StaticRestTemplate.getHttpClient();

String defaultURL = StaticRestTemplate.baseURL + "/cometd";

@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_conversations);

context = this;


try {
httpClient.start();
} catch (Exception e) {
e.printStackTrace();
}

if (isOnline()) {
new getConversationsForLoggedInUser(this).execute();

ClientTransport clientTransport = new LongPollingTransport(null, httpClient);
client = new BayeuxClient(defaultURL, clientTransport);
client.putCookie(new HttpCookie("JSESSIONID", StaticRestTemplate.getJsessionid()));
client.getChannel(Channel.META_HANDSHAKE).addListener(new InitializerListener());
client.getChannel(Channel.META_CONNECT).addListener(new ConnectionListener());
client.handshake();
boolean success = client.waitFor(2000, BayeuxClient.State.CONNECTED);
if (!success) {
Toast.makeText(getApplicationContext(), "Could not connect to PUSH service", Toast.LENGTH_LONG).show();
}

public class getConversationsForLoggedInUser extends AsyncTask<Void, Void, ResponseEntity<PrivateChannel[]>> {

client.getChannel("/person/"+privateChannel.getPrivateChannelName()).subscribe(chatListener);

// Here I get all conversations for user and load them in ListView using adapter
}
public void sendMessageToChatActivity(final String channelName, final Map<String,Object> outputData) {
// Here send the message to Chat activity.
Log.d("Msg",String.valueOf(outputData.toString()));
runOnUiThread(new Runnable() {
public void run() {
ChatMessagesActivity.recieveUpdatedMessage(channelName, outputData);
}
});
}

public static void recieveMessageFromChatActivity(String channelName, Map<String, Object> inputData){
//client.putCookie(new HttpCookie("JSESSIONID", StaticRestTemplate.getJsessionid()));
client.getChannel(channelName).publish(inputData);

}

private void initialize() {

}

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");
}

private class InitializerListener implements ClientSessionChannel.MessageListener {
@Override
public void onMessage(ClientSessionChannel channel, Message message) {
if (message.isSuccessful()) {
initialize();
}
}
}

private class ConnectionListener implements ClientSessionChannel.MessageListener {
private boolean wasConnected;
private boolean connected;

public void onMessage(ClientSessionChannel channel, Message message) {
if (client.isDisconnected()) {
connected = false;
connectionClosed();
return;
}
wasConnected = connected;
connected = message.isSuccessful();
if (!wasConnected && connected) {
connectionEstablished();
} else if (wasConnected && !connected) {
connectionBroken();
}
}
}

// THe below method sends message to the ChatMessagesActivity.
public class ChatListener implements ClientSessionChannel.MessageListener {
public void onMessage(ClientSessionChannel channel, Message message) {
sendMessageToChatActivity(channel.toString(),message);
}
}

聊天消息 Activity :

public class ChatMessagesActivity extends ApplicationDrawerLoader {
Context context;

public ListView chatList;

protected static ChatMessagesAdapter chatMessagesAdapter = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_messages);

chatList = (ListView) findViewById(R.id.chatList);
context = this;

sendMessageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Here I send message to ConversationActivity, which in turn sends it via CometdD.
sendMessageToConversationsActivity("/service/person/" + String.valueOf(conversationId), outputData);
}


public static void recieveUpdatedMessage(String channelName, Map<String, Object> input) {

// Here I recieve the new message and add it to adapter.
HashMap<String, String> insertMap = new HashMap<>();
// Add data to hashmap and add it to adapter
chatMessagesAdapter.add(insertMap);
chatMessagesAdapter.notifyDataSetChanged();
}
public void sendMessageToConversationsActivity(String channelName, Map<String, Object> output) {
ConversationActivity.recieveMessageFromChatActivity(channelName, output);
}

public class getPrivateChatsForUser extends AsyncTask<Void, Void, ResponseEntity<RestReplies[]>> {

ChatMessagesActivity chatMessagesActivity = null;

getPrivateChatsForUser(ChatMessagesActivity chatMessagesActivity) {
this.chatMessagesActivity = chatMessagesActivity;

}
// Here i get chat messages from network and load it in list-view using adapter.,


public class ChatMessagesAdapter extends BaseAdapter {

// Adapter code to display, nothing fancy.
}
}

我知道代码看起来有点长,但问题也是如此。我将不胜感激任何帮助。我不是 Android 专家,只是尝试集成它。谢谢。 :-)

编辑

public class CometdService extends Service {

protected static volatile BayeuxClient client;

String defaultURL = StaticRestTemplate.baseURL + "/cometd";


HttpClient httpClient = StaticRestTemplate.getHttpClient();

private ChatListener chatListener = new ChatListener();


@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
httpClient.start();
} catch (Exception e) {
e.printStackTrace();
}


ClientTransport clientTransport = new LongPollingTransport(null, httpClient);
client = new BayeuxClient(defaultURL, clientTransport);
client.putCookie(new HttpCookie("JSESSIONID", StaticRestTemplate.getJsessionid()));
client.getChannel(Channel.META_HANDSHAKE).addListener(new InitializerListener());
client.getChannel(Channel.META_CONNECT).addListener(new ConnectionListener());
client.handshake();
boolean success = client.waitFor(2000, BayeuxClient.State.CONNECTED);
if (!success) {
Toast.makeText(getApplicationContext(), "Could not connect to PUSH service", Toast.LENGTH_LONG).show();
}


return Service.START_REDELIVER_INTENT;
}

@Override
public void onDestroy() {

}

private class InitializerListener implements ClientSessionChannel.MessageListener {
@Override
public void onMessage(ClientSessionChannel channel, Message message) {
if (message.isSuccessful()) {
initialize();
}
}
}

private class ConnectionListener implements ClientSessionChannel.MessageListener {
private boolean wasConnected;
private boolean connected;

public void onMessage(ClientSessionChannel channel, Message message) {
if (client.isDisconnected()) {
connected = false;
connectionClosed();
return;
}
wasConnected = connected;
connected = message.isSuccessful();
if (!wasConnected && connected) {
connectionEstablished();
} else if (wasConnected && !connected) {
connectionBroken();
}
}
}

private void initialize() {

}

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");
}

public class ChatListener implements ClientSessionChannel.MessageListener {
public void onMessage(ClientSessionChannel channel, Message message) {
// sendMessageToChatActivity(channel.toString(), message);
}
}
}

新创建的服务,正在进行中。

最佳答案

看起来像 IntentService可能有助于与服务器的通信。

关于java - 安卓 : Keep httpclient running in background and communicate with activity when message recieved by httpclient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34763922/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com