我有一个XMPP服务器,我已设置发送和接收Firebase云消息,这些消息在测试期间一直运行正常,通过我的服务器代码中的以下两行打开调试:
config.setDebuggerEnabled(true);
XMPPConnection.DEBUG_ENABLED = true;
我现在想把它移到我的生产ec2实例中,这样做我必须将上面两行代码更改为false。进行此更改后,我的jar文件不再有效。
从CMD运行jar:
Microsoft Windows [Version 10.0.10586]
(c) 2015 Microsoft Corporation. All rights reserved.
C:\Users\Riley>cd "C:\Program Files\Java\jdk1.8.0_101\bin"
C:\Program Files\Java\jdk1.8.0_101\bin>java -jar D:\Downloads\XMPP-Chat-Server\server.jar
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.provider.UrlProviderFileInitializer initialize
INFO: Loading providers for file [classpath:META-INF/core.providers]
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.provider.ExtensionInitializer] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.ServiceDiscoveryManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.XHTMLManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.muc.MultiUserChat] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.filetransfer.FileTransferManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.LastActivityManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.commands.AdHocCommandManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.ping.PingManager] specified in smack-config.xml could not be loaded:
C:\Program Files\Java\jdk1.8.0_101\bin>
这是我的XMPP服务器代码:
package com.fcmserver;
/*
* Most part of this class is copyright Google.
* It is from https://developer.android.com/google/gcm/ccs.html
*/
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketInterceptor;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.DefaultPacketExtension;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.StringUtils;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.xmlpull.v1.XmlPullParser;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;
import javax.net.ssl.SSLSocketFactory;
/**
* Sample Smack implementation of a client for GCM Cloud Connection Server.
*
* For illustration purposes only.
*/
public class SmackCcsClient {
static final String REG_ID_STORE = "gcmchat.txt";
static final String MESSAGE_KEY = "SM";
Logger logger = Logger.getLogger("SmackCcsClient");
public static final String GCM_SERVER = "fcm-xmpp.googleapis.com";
public static final int GCM_PORT = 5235;
public static final String GCM_ELEMENT_NAME = "gcm";
public static final String GCM_NAMESPACE = "google:mobile:data";
static Random random = new Random();
XMPPConnection connection;
ConnectionConfiguration config;
/**
* XMPP Packet Extension for GCM Cloud Connection Server.
*/
class GcmPacketExtension extends DefaultPacketExtension {
String json;
public GcmPacketExtension(String json) {
super(GCM_ELEMENT_NAME, GCM_NAMESPACE);
this.json = json;
}
public String getJson() {
return json;
}
@Override
public String toXML() {
return String.format("<%s xmlns=\"%s\">%s</%s>", GCM_ELEMENT_NAME,
GCM_NAMESPACE, json, GCM_ELEMENT_NAME);
}
@SuppressWarnings("unused")
public Packet toPacket() {
return new Message() {
// Must override toXML() because it includes a <body>
@Override
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<message");
if (getXmlns() != null) {
buf.append(" xmlns=\"").append(getXmlns()).append("\"");
}
if (getLanguage() != null) {
buf.append(" xml:lang=\"").append(getLanguage())
.append("\"");
}
if (getPacketID() != null) {
buf.append(" id=\"").append(getPacketID()).append("\"");
}
if (getTo() != null) {
buf.append(" to=\"")
.append(StringUtils.escapeForXML(getTo()))
.append("\"");
}
if (getFrom() != null) {
buf.append(" from=\"")
.append(StringUtils.escapeForXML(getFrom()))
.append("\"");
}
buf.append(">");
buf.append(GcmPacketExtension.this.toXML());
buf.append("</message>");
return buf.toString();
}
};
}
}
public SmackCcsClient() {
// Add GcmPacketExtension
ProviderManager.getInstance().addExtensionProvider(GCM_ELEMENT_NAME,
GCM_NAMESPACE, new PacketExtensionProvider() {
@Override
public PacketExtension parseExtension(XmlPullParser parser)
throws Exception {
String json = parser.nextText();
GcmPacketExtension packet = new GcmPacketExtension(json);
return packet;
}
});
}
/**
* Returns a random message id to uniquely identify a message.
*
* <p>
* Note: This is generated by a pseudo random number generator for
* illustration purpose, and is not guaranteed to be unique.
*
*/
public String getRandomMessageId() {
return "m-" + Long.toString(random.nextLong());
}
/**
* Sends a downstream GCM message.
*/
public void send(String jsonRequest) {
Packet request = new GcmPacketExtension(jsonRequest).toPacket();
connection.sendPacket(request);
}
/**
* Handles an upstream data message from a device application.
*
* <p>
* This sample echo server sends an echo message back to the device.
* Subclasses should override this method to process an upstream message.
*/
public void handleIncomingDataMessage(Map<String, Object> jsonObject) {
String from = jsonObject.get("from").toString();
// PackageName of the application that sent this message.
String category = jsonObject.get("category").toString();
// Use the packageName as the collapseKey in the echo packet
String collapseKey = "echo:CollapseKey";
@SuppressWarnings("unchecked")
Map<String, String> payload = (Map<String, String>) jsonObject
.get("data");
String messageText = payload.get("message_text");
String messageFrom = payload.get("message_userfrom");
String messageTime = payload.get("message_timestamp");
String toUser = payload.get("message_recipient");
String id = payload.get("message_alarm_id");
String messageType = payload.get("binder_message_type");
payload.put("message_text", messageText);
payload.put("message_userfrom", messageFrom);
payload.put("message_timestamp", messageTime);
payload.put("message_alarm_id", id);
payload.put("binder_message_type", messageType);
String message = createJsonMessage(toUser, getRandomMessageId(),
payload, collapseKey, null, false);
send(message);
}
/**
* Handles an ACK.
*
* <p>
* By default, it only logs a INFO message, but subclasses could override it
* to properly handle ACKS.
*/
public void handleAckReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
logger.log(Level.INFO, "handleAckReceipt() from: " + from
+ ", messageId: " + messageId);
}
/**
* Handles a NACK.
*
* <p>
* By default, it only logs a INFO message, but subclasses could override it
* to properly handle NACKS.
*/
public void handleNackReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
logger.log(Level.INFO, "handleNackReceipt() from: " + from
+ ", messageId: " + messageId);
}
/**
* Creates a JSON encoded GCM message.
*
* @param to
* RegistrationId of the target device (Required).
* @param messageId
* Unique messageId for which CCS will send an "ack/nack"
* (Required).
* @param payload
* Message content intended for the application. (Optional).
* @param collapseKey
* GCM collapse_key parameter (Optional).
* @param timeToLive
* GCM time_to_live parameter (Optional).
* @param delayWhileIdle
* GCM delay_while_idle parameter (Optional).
* @return JSON encoded GCM message.
*/
public static String createJsonMessage(String to, String messageId,
Map<String, String> payload, String collapseKey, Long timeToLive,
Boolean delayWhileIdle) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("to", to);
if (collapseKey != null) {
message.put("collapse_key", collapseKey);
}
if (timeToLive != null) {
message.put("time_to_live", timeToLive);
}
if (delayWhileIdle != null && delayWhileIdle) {
message.put("delay_while_idle", true);
}
message.put("priority", "high");
message.put("message_id", messageId);
message.put("data", payload);
return JSONValue.toJSONString(message);
}
/**
* Creates a JSON encoded ACK message for an upstream message received from
* an application.
*
* @param to
* RegistrationId of the device who sent the upstream message.
* @param messageId
* messageId of the upstream message to be acknowledged to CCS.
* @return JSON encoded ack.
*/
public static String createJsonAck(String to, String messageId) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("message_type", "ack");
message.put("to", to);
message.put("message_id", messageId);
return JSONValue.toJSONString(message);
}
/**
* Connects to GCM Cloud Connection Server using the supplied credentials.
*
* @param username
* GCM_SENDER_ID@gcm.googleapis.com
* @param password
* API Key
* @throws XMPPException
*/
public void connect(String username, String password) throws XMPPException {
config = new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
config.setSecurityMode(SecurityMode.enabled);
config.setReconnectionAllowed(true);
config.setRosterLoadedAtLogin(false);
config.setSendPresence(false);
config.setSocketFactory(SSLSocketFactory.getDefault());
// NOTE: Set to true to launch a window with information about packets
// sent and received
config.setDebuggerEnabled(false);
// -Dsmack.debugEnabled=true
XMPPConnection.DEBUG_ENABLED = false;
connection = new XMPPConnection(config);
connection.connect();
connection.addConnectionListener(new ConnectionListener() {
@Override
public void reconnectionSuccessful() {
logger.info("Reconnecting..");
}
@Override
public void reconnectionFailed(Exception e) {
logger.log(Level.INFO, "Reconnection failed.. ", e);
}
@Override
public void reconnectingIn(int seconds) {
logger.log(Level.INFO, "Reconnecting in %d secs", seconds);
}
@Override
public void connectionClosedOnError(Exception e) {
logger.log(Level.INFO, "Connection closed on error.");
}
@Override
public void connectionClosed() {
logger.info("Connection closed.");
}
});
// Handle incoming packets
connection.addPacketListener(new PacketListener() {
@Override
public void processPacket(Packet packet) {
logger.log(Level.INFO, "Received: " + packet.toXML());
Message incomingMessage = (Message) packet;
GcmPacketExtension gcmPacket = (GcmPacketExtension) incomingMessage
.getExtension(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() {
@Override
public void interceptPacket(Packet packet) {
logger.log(Level.INFO, "Sent: {0}", packet.toXML());
}
}, new PacketTypeFilter(Message.class));
connection.login(username, password);
}
public void writeToFile(String name, String regId) throws IOException {
Map<String, String> regIdMap = readFromFile();
regIdMap.put(name, regId);
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(
REG_ID_STORE, false)));
for (Map.Entry<String, String> entry : regIdMap.entrySet()) {
out.println(entry.getKey() + "," + entry.getValue());
}
out.println(name + "," + regId);
out.close();
}
public Map<String, String> readFromFile() {
Map<String, String> regIdMap = null;
try {
BufferedReader br = new BufferedReader(new FileReader(REG_ID_STORE));
String regIdLine = "";
regIdMap = new HashMap<String, String>();
while ((regIdLine = br.readLine()) != null) {
String[] regArr = regIdLine.split(",");
regIdMap.put(regArr[0], regArr[1]);
}
br.close();
} catch(IOException ioe) {
}
return regIdMap;
}
public static void main(String [] args) {
final String userName = "USERNAME" + "@gcm.googleapis.com";
final String password = "PASSWORD";
SmackCcsClient ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:0)
所以我想出来了。我更改了以下代码:
public static void main(String [] args) {
final String userName = "USERNAME" + "@gcm.googleapis.com";
final String password = "PASSWORD";
SmackCcsClient ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
以下内容:
public static void main(String [] args) {
final String userName = "USERNAME" + "@gcm.googleapis.com";
final String password = "PASSWORD";
SmackCcsClient ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
try {
CountDownLatch latch = new CountDownLatch(1);
latch.await();
} catch (InterruptedException e) {
logger.log(Level.SEVERE, "An error occurred while latch was waiting.", e);
}
}
}
}