- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我已经为 Android 应用程序和 Web 服务器之间的双向消息实现了新的 GCM CCS。下游消息(网络设备)完美运行。不幸的是,服务器上没有收到上游消息(设备网络)。它们似乎是在客户端发送的(请参阅下面的 Android 应用程序日志消息),但服务器没有收到任何内容。
D/GCM﹕ GcmService start Intent { act=com.google.android.gcm.intent.SEND flg=0x10 pkg=com.google.android.gms cmp=com.google.android.gms/.gcm.GcmService (has extras) } com.google.android.gcm.intent.SEND
我认为 Android 端没有问题,但服务器端没有问题。问题是,我无法找出问题所在,因为连接仍然存在,而且我确实从 GCM 服务器收到了一些消息,比如 ACK。那么为什么没有收到正常的消息呢?有人知道吗?
其他一些值得一提的细节是所使用的 Web 服务器是 Glassfish 并且我在 Servlet 中启动了 XMPP 连接。下面是一些片段。
编辑:正如我在回答中所述,阻止任何服务器接收消息的主要问题已经解决。但是,仍然有相当多的消息没有收到(大约 50%)。
例如,每当用户在 Android 应用程序中进行更改时(按下按钮,因此每批 2 条消息之间至少有几秒钟的时间),我会在后台线程上一个接一个地立即发送 2 条消息.有时我在服务器上收到两条消息,有时我只收到其中一条,有时甚至什么都没有发生……这是一个严重的问题,特别是对于核心依赖该技术的应用程序。任何人都可以提供进一步的帮助来解决这个问题吗?
更多信息:我很确定这与客户端不相关,因为每条消息都在发送,就像您在上面的 logcat 日志中看到的那样,我也收到了“事件:已发送”GCM 会在一段时间后广播(虽然不是立即,可能是 5 分钟)。所以它必须是基于 GCM 或基于服务器的东西。
public class CcsServlet extends HttpServlet
{
private static Logger logger = Logger.getLogger(CcsServlet.class.getName());
public void init(ServletConfig config) throws ServletException
{
CcsManager ccsManager = CcsManager.getInstance();
try
{
ccsManager.connect();
}
catch (Exception e)
{
logger.warning("Cannot connect to CCS server.");
e.printStackTrace();
}
}
}
public class CcsManager
{
private static XMPPConnection connection;
private static Logger logger = Logger.getLogger(CcsManager.class.getName());
public static final String GCM_SERVER = "gcm.googleapis.com";
public static final int GCM_PORT = 5235;
private static CcsManager sInstance = null;
private static final String USERNAME = "xxxxxxxxxx" + "@gcm.googleapis.com";
private static final String PASSWORD = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
public CcsManager()
{
// Add GcmPacketExtension
ProviderManager.getInstance().addExtensionProvider(
GcmPacketExtension.GCM_ELEMENT_NAME,
GcmPacketExtension.GCM_NAMESPACE, new PacketExtensionProvider()
{
public PacketExtension parseExtension(XmlPullParser parser) throws Exception
{
String json = parser.nextText();
return new GcmPacketExtension(json);
}
});
}
public static CcsManager getInstance()
{
if (sInstance == null)
sInstance = new CcsManager();
return sInstance;
}
/**
* Connects to GCM Cloud Connection Server
*/
public void connect() throws IOException, XMPPException
{
ConnectionConfiguration config = new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
config.setReconnectionAllowed(true);
config.setRosterLoadedAtLogin(false);
config.setSendPresence(false);
config.setSocketFactory(SSLSocketFactory.getDefault());
config.setDebuggerEnabled(false);
connection = new XMPPConnection(config);
connection.connect();
connection.addConnectionListener(new ConnectionListener()
{
public void reconnectionSuccessful()
{
logger.info("Reconnecting..");
}
public void reconnectionFailed(Exception e)
{
logger.log(Level.INFO, "Reconnection failed.. ", e);
}
public void reconnectingIn(int seconds)
{
logger.log(Level.INFO, "Reconnecting in %s secs", seconds);
}
public void connectionClosedOnError(Exception e)
{
logger.info("Connection closed on error.");
}
public void connectionClosed()
{
logger.info("Connection closed.");
}
});
// Handle incoming packets
connection.addPacketListener(new PacketListener()
{
public void processPacket(Packet packet)
{
logger.log(Level.INFO, "Received: " + packet.toXML());
Message incomingMessage = (Message) packet;
GcmPacketExtension gcmPacket =
(GcmPacketExtension) incomingMessage.getExtension(GcmPacketExtension.GCM_NAMESPACE);
String json = gcmPacket.getJson();
try
{
@SuppressWarnings("unchecked")
Map<String, Object> jsonObject =
(Map<String, Object>) JSONValue.parseWithException(json);
// present for "ack"/"nack", null otherwise
Object messageType = jsonObject.get("message_type");
if (messageType == null)
{
// Normal upstream data message
handleIncomingDataMessage(jsonObject);
// Send ACK to CCS
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
String ack = createJsonAck(from, messageId);
send(ack);
}
else if ("ack".equals(messageType.toString()))
{
// Process Ack
handleAckReceipt(jsonObject);
}
else if ("nack".equals(messageType.toString()))
{
// Process Nack
handleNackReceipt(jsonObject);
}
else
{
logger.log(Level.WARNING, "Unrecognized message type (%s)",
messageType.toString());
}
}
catch (ParseException e)
{
logger.log(Level.SEVERE, "Error parsing JSON " + json, e);
}
catch (Exception e)
{
logger.log(Level.SEVERE, "Couldn't send echo.", e);
}
}
}, new PacketTypeFilter(Message.class));
// Log all outgoing packets
connection.addPacketInterceptor(new PacketInterceptor()
{
public void interceptPacket(Packet packet)
{
logger.log(Level.INFO, "Sent: {0}", packet.toXML());
}
}, new PacketTypeFilter(Message.class));
connection.login(USERNAME, PASSWORD);
}
}
最佳答案
Web 应用程序似乎在服务器上部署了两次。这导致创建 XMPP 连接的 servlet 被初始化一次,然后销毁,然后再次初始化。这个序列对于连接到 GCM (dho..) 可能不是一件好事。
只需确保 servlet 只初始化一次。通过在其 init() 和 destroy() 方法中使用记录器来检查这一点。如果确实调用了不止一次,尝试将web模块分配给特定的虚拟服务器进行部署。我相信这因 Web 服务器而异。对于 Glassfish,您需要在管理控制台 (localhost:4848) 中执行此操作。
这解决了更大的问题。我遇到的另一个问题是上游消息传递根本不可靠。有时来自同一设备的多个连续上行消息完美无缺地工作,只是为了尝试另一个根本没有推送到服务器的消息。还没有找到解决这个问题的任何模式...如果我发现其他问题,我会回来的。
编辑:显然在本地服务器上使用该实现时出现问题。移至远程服务器(暂存 VPS),问题似乎消失了。服务器接收每条消息。如果问题仍然存在,我会回来,但我对此表示怀疑。我认为本地问题是由于我的 ISP,或者甚至是我的本地 Wi-Fi 连接造成的。对于究竟是什么原因造成的,我没有一个完整的答案,但至少它在登台服务器上运行得很好。
关于java - GCM CCS 服务器实现未接收上游消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23366588/
ccs.exe是什么进程? 进程 CCS 是附属于软件 Cisco Configuration Service (CCS) 或 Cisco Configuration Service 由 Cisc
我是这里的新手,但有一个问题没有答案。我正在使用来自德克萨斯州的 TM4C1294,代码中存在无数错误。但首先,我有这段代码。您可以看到,x3 具有从 PIN ADC0 读取的数据,但在 channe
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
我想设置一个 3 秒的计时器。这样程序将遵循一条指令 3 秒钟,然后再遵循其他指令集。 20MHz,图片 16F877A。 最佳答案 CCS web page 上有一个例子为您完全相同的图片和时钟称为
我现在正在使用设备 CC1310 在 CCS(Code Composer Studio)中做一个项目。我想值得一提的是,我对 CCS 还比较陌生。 我很难找到一种简单的方法来从板上的 PINS 读取模
我的 LED 有问题。 2 个按钮作为输入,3 个 LED 和 7 段显示器作为输出。如果我们按一次选择按钮,我们可以在七段显示器上观察到“1”。当按下确认按钮时,按下确认按钮后1秒绿色LED将亮起。
我有一个代码,需要在定时器中断中读取 AD channel (具有精确时间)。 只要我读完广告就一切都好。但我需要使用数字滤波器,如果我只在中断中放入乘法,则会出现警告: 这样就可以了: #int_R
我正在尝试将“msp.h”包含在 CCS v9 项目中,以便运行我正在阅读的书中的代码。下面是一个示例代码片段: * This program toggles green LED for 0.5 s
我正在使用 CCS 编译器,并且对于这段代码,会收到一条警告,表明条件始终为真。这是 PIC16F877 的代码,因此当输入为 1 时,它应该跳出循环。我在这里遗漏了什么吗? int read_key
(如果有人能指出如何在不使用不起作用的 4 空格缩进系统的情况下将代码粘贴到此处,我很乐意发布代码) 大家好经过大约 9 个小时的绞尽脑汁,我找不到答案,也找不到我的计算出了问题的地方……但事实确实如
我正在使用 java 服务器发送消息以使用谷歌云消息。但是当我发送消息时,我收到了“项目 ** 未列入白名单” 我已经在 https://services.google.com/fb/forms/gc
我有一个带有输入框描述性标签的表单,该输入框换行到表单窗口中的第二行。这本身就很好,但输入框最终搞砸了,因为它似乎与标签的顶部而不是底部对齐。问题是,如何让输入框对齐到标签的底部? 这是所涉及元素的
关于如何在电子邮件签名中附加图形的老问题。 IE。我可以将图像附加为链接,这意味着 outlook 用户将看不到它。我可以将它们嵌入为编码图像,但只有从 outlook(我们同时使用 gmail 和
我有一个导航菜单,它使用 CSS 媒体查询进行响应。当导航在台式机/笔记本电脑 View 中时,整个菜单都可以正常工作。导航标签放置在笔记本电脑桌面 View 中的图像下方,这是我想要的,但是当它处于
我想更改搜索栏上的水印文本和弹出文本。我想用一些 CCS 来做。我知道不推荐这样做,但我认为这是最快的方法。 我已阅读How can I replace text with CSS?和 How to
我使用纯 CSS 根据页面的视口(viewport)创建一个动态打开和关闭的侧边栏。但是我的代码有几个问题: 如何在屏幕首次加载时阻止动画?也就是说,我只想在第一次加载时打开或关闭侧边栏,然后在调整视
我已经为 Android 应用程序和 Web 服务器之间的双向消息实现了新的 GCM CCS。下游消息(网络设备)完美运行。不幸的是,服务器上没有收到上游消息(设备网络)。它们似乎是在客户端发送的(请
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我正在尝试通过 C# 发送/接收字符串,在 C# 中我只是这样做: SerialPort.WriteLine("A6"); 但在 CCS 中,如果我尝试在 char 之后发送一个字符串 char,它根
当我在 Windows XP 上使用 Eclipse/CCS (CDT) 时,“开放声明”( F3 ) 和“开放定义”( Ctrl-F3 ) 操作按预期运行。 切换到 Windows 7 后,我仍然可
我是一名优秀的程序员,十分优秀!