I have implemented the XMPP server as described in the google api.
The main function that was written is sending a downstream message. I used while(true) loop to keep the server running.
I was wondering what is the best practice for keeping the server app awake and process messages.
public static void main(String[] args) throws Exception {
final long senderId = ***; // your GCM sender id
final String password = "***";
SmackCcsClient ccsClient = new SmackCcsClient();
ccsClient.connect(senderId, password);
while(true){}
}
Related
For approximately one week I have been trying to create a simple chat-program to learn how to use datagrams and sockets, proceeding with success I'm now trying to make a more functional final version of it, to test what I have learned but I have run into a huge problem.
Sending packets between two local computers is easy as a breeze, but when it comes to sending them to other computers on the internet port-forwarding have been an issue. Looking into this I discovered UPnP and created an automatic UPnP port on the client using Cling to make it more user-friendly, server-side I always port-forward "manually", which means it can always receive under normal circumstances. but the client is facing a problem I didn't anticipate: they can't receive datagrams through the UPnP port. if you port forward them "manually" they can receive (they can always send though, and the server reads them loud and clear).
So my question is: can someone show me how to send/receive (don't know if it's the servers fault or the clients fault, problem lies either in how the server receives, or how the client sends) through UPnP ports? or am I using UPnP ports all wrong? my router, which is the test subject, have UPnp port enabled, and I have tested UDP and TCP ports along with datagramsockets and multicastsockets in every configuration I could think of.
TL:DR use UPnP or find other solution on how to send/receive datagrams through a router/modem.
I am extremely sorry if the code is a bit messy/buggy, not the full code, will post pastebin if asked.
Client:
public class Client {
public MulticastSocket rsocket = new MulticastSocket(25566);
public Client() throws IOException {
//creating UPnP port using Cling...
InetAddress inet = InetAddress.getLocalHost();
PortMapping desiredMapping = new PortMapping(25566,
inet.getHostAddress(), PortMapping.Protocol.UDP,
"Chatt program");
UpnpServiceImpl upnpService = new UpnpServiceImpl(
new PortMappingListener(desiredMapping));
upnpService.getControlPoint().search();
// loop the loop to get values from text fields used
// to receive messages from the server.
//point of interest, this is where the client should receive data, works on a normal
//portforward, doesn't on a UPnP port, no idea why.
byte[] info = new byte[256];
while (true) {
DatagramPacket receive = new DatagramPacket(info, info.length);
rsocket.receive(receive);
String rmessage = new String(receive.getData(), 0,receive.getLength());
System.Out.println(rmessage);
}
}
public static void main(String[] args) throws IOException {
new Client();
}
}
Server:
public class Server {
public MulticastSocket rsocket = new MulticastSocket(25565);
public Server() throws IOException {
String rmessage = new String("a message");
// send to clients, not working on UPnP port
send(rmessage, 25566);
}
public void send(String msg, int port) throws IOException {
byte[] message = msg.getBytes();
DatagramPacket gpacket = new DatagramPacket(message,message.length, address, 25566);
rsocket.send(gpacket);
}
public static void main(String[] args) throws IOException {
new Server();
}
}
I am trying to listen for new messages using the POP3 protocol. I am aware that Pop3 doesn't allow new messages to appear in the Inbox while the folder is open. Below is the code that I have implemented:
import javax.mail.event.MessageCountAdapter;
import javax.mail.event.MessageCountEvent;
public class EmailListener extends MessageCountAdapter {
public EmailListener() {
}
public void messagesAdded(MessageCountEvent e) {
System.out.println("I");
}
public void messagesRemoved(MessageCountEvent e) {
System.out.println("J");
}
}
public class POPReceiver {
public POPReceiver() {
}
public void listen() throws Exception {
Properties properties = new Properties();
Session session = null;
POP3Store pop3Store = null;
String host = "NB-EX101.example.com";
String user = "user2";
properties.put(mail.pop3.host, host);
session = Session.getDefaultInstance(properties);
pop3Store = (POP3Store) session.getStore("pop3");
pop3Store.connect(user, "password");
Folder folder = pop3Store.getFolder("INBOX");
folder.addMessageCountListener(new EmailListener());
sendEmail();
}
public void sendEmail() {
// not added code, but the email sends
}
}
public static void main(String[] args) throws Exception {
POPReceiver i = new POPReceiver();
i.listen();
}
I am using Microsoft Exchange Server. Any ideas why it is not listening?
I have looked on http://www.coderanch.com/t/597347/java/java/Email-Listener but still does not listen.
From Javamail FAQ (http://www.oracle.com/technetwork/java/javamail/faq/index.html):
Q: I set up a MessageCountListener (as demonstrated in the monitor program) but I'm never notified of new mail in my POP3 INBOX.
A: The POP3 protocol does not allow the client to see new messages delivered to the INBOX while the INBOX is open. The application must close the INBOX and reopen it in order to see any new messages. You will never be notified of new mail using the MessageCountListener interface with POP3. See the com.sun.mail.pop3 package documentation for more information.
So, MessageCountListener will not work for POP3. You'll need to implement polling to get information about new messages for POP3.
However, you can try using IMAP instead.
But even in the case of IMAP you should be using this in another way. See idle() method in IMAPStore class (e.g. being called in a loop in a separate thread etc - see https://javamail.java.net/nonav/docs/api/com/sun/mail/imap/IMAPStore.html#idle() ).
Very little documentation, above what exists in the sample code is currently available for Grizzly 2.2 and I have found this to be most difficult to navigate as it relates to SSL implementation. I am desperately in need of some guidance in this area. After reviewing my code to determine what I need to post in order to pose a complete question, I realized it might be most beneficial to first cement the basics.
Below are three classes provided by the Grizzly project in order to demonstrate a sample implementation of Grizzly's SSL capabilities. Besides the removal of comments, the code is identical to the 2.2.19 released code base as maintained in git at git://java.net/grizzly~git and also available here.
The git repository also provides the referenced truststore and keystore.
EchoFilter:
public class EchoFilter extends BaseFilter{
#Override
public NextAction handleRead(FilterChainContext ctx)throws IOException {
//|Peer address is used for non-connected UDP Connection
final Object peerAddress = ctx.getAddress();
final Object message = ctx.getMessage();
ctx.write(peerAddress, message, null);
return ctx.getStopAction();
}
}
SSLEchoServer:
public class SSLEchoServer{
public static final String HOST = "localhost";
public static final int PORT = 7777;
public static void main(String[] args) throws IOException{
//|Create a FilterChain using FilterChainBuilder
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
//|Add TransportFilter, which is responsible for reading and writing data to the connection
filterChainBuilder.add(new TransportFilter());
//|Initialize and add SSLFilter
final SSLEngineConfigurator serverConfig = initializeSSL();
final SSLEngineConfigurator clientConfig = serverConfig.copy().setClientMode(true);
filterChainBuilder.add(new SSLFilter(serverConfig, clientConfig));
//|Add StringFilter, which will be responsible for Buffer <-> String transformation
filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));
//|Use the plain EchoFilter
filterChainBuilder.add(new EchoFilter());
//|Create TCP transport
final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
//|Set filterchain as a Transport Processor
transport.setProcessor(filterChainBuilder.build());
try{
//|Binding transport to start listen on certain host and port
transport.bind(HOST, PORT);
//|Start the transport
transport.start();
System.out.println("Press any key to stop the server...");
System.in.read();
}finally{
System.out.println("Stopping transport...");
//|Stop the transport
transport.stop();
System.out.println("Stopped transport...");
}
}
private static SSLEngineConfigurator initializeSSL(){
//|Initialize SSLContext configuration
SSLContextConfigurator sslContextConfig = new SSLContextConfigurator();
//|Set key store
ClassLoader cl = SSLEchoServer.class.getClassLoader();
URL cacertsUrl = cl.getResource("ssltest-cacerts.jks");
if(cacertsUrl != null){
sslContextConfig.setTrustStoreFile(cacertsUrl.getFile());
sslContextConfig.setTrustStorePass("changeit");
}
//|Set trust store
URL keystoreUrl = cl.getResource("ssltest-keystore.jks");
if(keystoreUrl != null){
sslContextConfig.setKeyStoreFile(keystoreUrl.getFile());
sslContextConfig.setKeyStorePass("changeit");
}
//|Create SSLEngine configurator
return new SSLEngineConfigurator(sslContextConfig.createSSLContext(), false, false, false);
}
}
SSLEchoClient:
public class SSLEchoClient{
private static final String MESSAGE = "Hello World!";
public static void main(String[] args) throws IOException{
//|Create a FilterChain using FilterChainBuilder
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
//|Add TransportFilter, which is responsible for reading and writing data to the connection
filterChainBuilder.add(new TransportFilter());
//|Initialize and add SSLFilter
final SSLEngineConfigurator serverConfig = initializeSSL();
final SSLEngineConfigurator clientConfig = serverConfig.copy().setClientMode(true);
final SSLFilter sslFilter = new SSLFilter(serverConfig, clientConfig);
filterChainBuilder.add(sslFilter);
//|Add StringFilter, which will be responsible for Buffer <-> String transformation
filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));
//|Add Filter, which will send a greeting message and check the result
filterChainBuilder.add(new SendMessageFilter(sslFilter));
//|Create TCP transport
final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
//|Set filterchain as a Transport Processor
transport.setProcessor(filterChainBuilder.build());
try{
//|Start the transport
transport.start();
//|Perform async. connect to the server
transport.connect(SSLEchoServer.HOST, SSLEchoServer.PORT);
System.out.println("Press any key to stop the client...");
System.in.read();
}finally{
System.out.println("Stopping transport...");
//|Stop the transport
transport.stop();
System.out.println("Stopped transport...");
}
}
private static class SendMessageFilter extends BaseFilter{
private final SSLFilter sslFilter;
public SendMessageFilter(SSLFilter sslFilter){
this.sslFilter = sslFilter;
}
#Override
#SuppressWarnings("unchecked")
public NextAction handleConnect(FilterChainContext ctx) throws IOException{
final Connection connection = ctx.getConnection();
//|Execute async SSL handshake
sslFilter.handshake(connection, new EmptyCompletionHandler<SSLEngine>(){
//|Once SSL handshake will be completed - send greeting message
#Override
public void completed(SSLEngine result){
//|Here we send String directly
connection.write(MESSAGE);
}
});
return ctx.getInvokeAction();
}
#Override
public NextAction handleRead(FilterChainContext ctx) throws IOException{
//|The received message is String
final String message = (String) ctx.getMessage();
//|Check the message
if(MESSAGE.equals(message)){
System.out.println("Got echo message: \"" + message + "\"");
}else{
System.out.println("Got unexpected echo message: \"" + message + "\"");
}
return ctx.getStopAction();
}
}
private static SSLEngineConfigurator initializeSSL(){
//|Initialize SSLContext configuration
SSLContextConfigurator sslContextConfig = new SSLContextConfigurator();
//|Set key store
ClassLoader cl = SSLEchoClient.class.getClassLoader();
URL cacertsUrl = cl.getResource("ssltest-cacerts.jks");
if(cacertsUrl != null){
sslContextConfig.setTrustStoreFile(cacertsUrl.getFile());
sslContextConfig.setTrustStorePass("changeit");
}
//|Set trust store
URL keystoreUrl = cl.getResource("ssltest-keystore.jks");
if(keystoreUrl != null){
sslContextConfig.setKeyStoreFile(keystoreUrl.getFile());
sslContextConfig.setKeyStorePass("changeit");
}
//|Create SSLEngine configurator
return new SSLEngineConfigurator(sslContextConfig.createSSLContext(), false, false, false);
}
}
When executing:
Run SSLEchoServer:
Press any key to stop the server...
Run SSLEchoClient:
Press any key to stop the client...
Question:
What is this code supposed to accomplish or demonstrate? Beyond the console output you see above, this code does nothing on my end.
In reviewing the code, my expectation was that the client was supposed start its TCP transport and connect it to the server. In the process of that connection being made, the SendMessageFilter previously added to the filter stream will execute its handleConnect() method, which I confirmed does execute. But, this code never executes the connection.write(MESSAGE) statement.
It's clear the intention here is to execute the write() method after the handshake thread completes, but it doesn't appear to do so, and in examining the handshake() method in SSLFilter class in grizzly-framework-2.2.19, I was also unable to determine where the overridden parent completed() method is even defined.
Can anyone lend some insight to whether this disconnect is due to my lack of understanding something here or if it is potentially a bug in the sample implementation provided by Grizzly? I believe clearing this up will go a long way to further my understanding here. Thank you in advance!
The question is in the title but to elaborate a bit. If I'm writing an NIO application in Java using the Sun/Oracle NIO APIs or a framework like Netty, is it possible to have a client "connect" as a subscriber even while there is no server bound to the host/port it connects to? What I effectively want to do is just not care if the server is dead but as soon as it is online and sends a message I receive it as if it was there the whole time. Take this ZMQ server and client for e.g.
Starting the client first....
import org.zeromq.ZMQ;
import java.util.Date;
public class ZMQClient {
public static void main(String[] args) {
// Prepare our context and subscriber
ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket subscriber = context.socket(ZMQ.SUB);
subscriber.connect("tcp://localhost:5563");
subscriber.subscribe("".getBytes());
while (true) {
// Read envelope with address
String address = new String(subscriber.recv(0));
// Read message contents
String contents = new String(subscriber.recv(0));
System.out.println(address + " : " + contents+" - "+ new Date());
}
}
}
...and some time later the server
import org.zeromq.ZMQ;
import java.util.Date;
public class ZMQServer {
public static void main(String[] args) throws Exception{
// Prepare our context and publisher
ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket publisher = context.socket(ZMQ.PUB);
publisher.bind("tcp://127.0.0.1:5563");
while (true) {
// Write two messages, each with an envelope and content
publisher.send("".getBytes(), ZMQ.SNDMORE);
publisher.send("We don't want to see this".getBytes(), 0);
publisher.send("".getBytes(), ZMQ.SNDMORE);
publisher.send("We would like to see this".getBytes(), 0);
System.out.println("Sent # "+new Date());
Thread.sleep(1000);
}
}
}
ZMQ supports this behavior (allowing clients to subscribe, etc., before the server is up) because it spawns a separate thread for handling socket communication. If the endpoint of the socket is not available, the thread takes care of queuing requests until the connection becomes available. This is all done transparently for you.
So, sure, you could probably adopt this technique for other APIs, but you'd have to take care of all the grunt work itself.
I have a server-client pair and I want to create a listener on the client end for new server responses. I am not sure how to do this, right now I can only interact in a direct synchronous way.
Here is the server:
public class TestServer {
public static void main(String[] args) throws Exception {
TestServer myServer = new TestServer();
myServer.run();
}
private void run() throws Exception {
ServerSocket mySS = new ServerSocket(4443);
while(true) {
Socket SS_accept = mySS.accept();
BufferedReader myBR = new BufferedReader(new InputStreamReader(SS_accept.getInputStream()));
String temp = myBR.readLine();
System.out.println(temp);
if (temp!=null) {
PrintStream serverPS = new PrintStream(SS_accept.getOutputStream());
serverPS.println("Response received: " + temp);
}
}
}
}
As you can see, it sends a response when it gets one. However in general I won't be sure when other servers I use send responses, so I would like to create an asynchronous listener (or at least poll the server for a response every half-second or so).
Here is what I'm trying on the client end:
protected static String getServerResponse() throws IOException {
String temp;
try {
BufferedReader clientBR = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
temp = clientBR.readLine();
} catch (Exception e) {
temp = e.toString();
}
return temp;
}
And just for reference, yes, sending over data from client to server works fine (it System.out's the data correctly). However, when I call the above function to try and retrieve the server response, it just hangs my application, which is an Android application in case that's relevant.
What I want from a function is just the ability to ask the server if it has data for me and get it, and if not, then don't crash my damn app.
On the client side create a ConnectionManager class which will handle all the socket I/O. The ConnectionManager's connect() method will create and start a new thread which will listen for server responses. As soon as it will receive a response it will notify all the ConnectionManager's registered listeners. So in order to receive asynchronously the server responses you will have to register a listener in ConnectionManager using its register(SomeListener) method.
Also, you can have a look at JBoss Netty which is an asynchronous event-driven network application framework. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.