I have setup my open fire(jabber server) on local machine with two user testuser1 and testuser2 .using Spark client both users perform chat without any issue,it's nice.
openfire IP -192.168.1.65
I want to use smack API(3.3.0) for send and receiving message. i have write sender side code to send message(with testuser1) and tested with Spark client(with testuser2) message received on testuser2 side,but when i try with java code to receive sender message ,i am not able to receive those publish messages.
Sender.java
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.MessageListener;
public class Sender
{
public static void main(String a[]) throws XMPPException, InterruptedException
{
XMPPConnection connection = new XMPPConnection("192.168.1.65");
System.out.println(connection);
connection.connect();
connection.login("testuser1", "test123");
Chat chat = connection.getChatManager().createChat("testuser2#sameek", new MessageListener() {
public void processMessage(Chat chat, Message message) {
// Print out any messages we get back to standard out.
System.out.println("Received message: " + message);
}
});
chat.sendMessage("Howdy test1!");
while (true) {
Thread.sleep(50);
}
}
}
Receiver.java
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.MessageListener;
public class Receiver
{
public static void main(String a[]) throws XMPPException,, InterruptedException
{
XMPPConnection connection = new XMPPConnection("192.168.1.65");
System.out.println(connection);
connection.connect();
connection.login("testuser2", "test123");
Chat chat = connection.getChatManager().createChat("testuser1#sameek", new MessageListener() {
public void processMessage(Chat chat, Message message) {
// Print out any messages we get back to standard out.
System.out.println("Received message: " + message);
}
});
chat.sendMessage("Howdy test2!");
while (true) {
Thread.sleep(50);
}
}
}
please help me and suggest if i am following wrong approach.
Thanks
I had a similar problem, after following the tutorial here (http://www.javacodegeeks.com/2010/09/xmpp-im-with-smack-for-java.html) and this is what I found:
When you create the chat, you chat the user you want to connect to (eg in my case "user1#gbd038"). This works fine if user1 is using a GUI client such as Spark (which presumably has built-in support and/or error handling for this), and user1 will receive the message. This process attaches the messageListener to a chat now associated with "user1#gbd038". However, when I reply from Spark as user1, the chat that smack receives is actually coming through complete with the location tag, eg:
Received message 'hi' from user1#gbd038/Spark 2.6.3
So it creates a new chat that the application is not listening for (and therefore your application will not receive / print out). I have found two ways to solve this problem:
use the location tag when starting the conversation (although this doesn't seem very scalable or robust):
xmppManager.sendMessage("Hello mate", "user1#gbd038/Spark 2.6.3");
as Robin suggested, use a ChatManagerListener (which will create a new chat when receiving the reply from user1, which can be forwarded to the messageListener):
chatManager = connection.getChatManager();
messageListener = new MyMessageListener();
chatManagerListener = new ChatManagerListener() {
#Override
public void chatCreated(Chat chat, boolean createdLocally) {
chat.addMessageListener(messageListener);
}
};
chatManager.addChatListener(chatManagerListener);
Hope that helps someone in the same position!
You are creating a chat and sending a chat message from both ends but not listening for a chat from either. Use a ChatManagerListener to listen for incoming chats from other clients.
Related
I have created a very very basic java server with tutorials. The goal is to let gamemaker studio 2 clients connect and communicate with that server. I have more experience with GML.
So the server is starting(java) up and the client(GMS2) is connecting succesfully. I have buildin some checks to make sure. If the client send a message to the server, the server never gets it, until the clients disconnect.
this is the java code:
import java.net.*;
import java.io.*;
public class GameServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(6666);
Socket client = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.println("hello gamemaker studio: "); //the clients receive this message
while(true) {
System.out.println("in while loop");//the server console prints this message
String string = in.readLine();//keeps stuck on this
//after client disconnect, all messages the client has sent are displayed in the console
System.out.println("reading string:" + string);
if (string == null) { break; }
out.println("we have received this answer: " + string );
System.out.println("stopped");
}
}
}
For some reason i don't know it is keeps stuck on this line:
String string = in.readLine();
I crafted a java client to test it. Everything works fine with a java client.
So there has to be something wrong with the gamemaker code
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() ).
Server
import java.util.concurrent.atomic.AtomicReference;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.spdy.DefaultSpdySynStreamFrame;
public class SpdyChannelUpStreamHandler extends SimpleChannelUpstreamHandler {
volatile Channel channel;
final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
#Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
System.out.println("Channel In Open Stage");
channel = e.getChannel();
}
#Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
System.out.println("Channel In Connected Stage");
Channels.write(channel, new DefaultSpdySynStreamFrame(1, 1, (byte)0));
}
#Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
System.out.println("Message Received on Server Side");
Channels.write(channel, e.getMessage(), e.getRemoteAddress());
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
if (exception.compareAndSet(null, e.getCause())) {
e.getChannel().close();
}
}
}
import static org.jboss.netty.channel.Channels.pipeline;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.spdy.SpdyFrameDecoder;
import org.jboss.netty.handler.codec.spdy.SpdyFrameEncoder;
import org.jboss.netty.handler.codec.spdy.SpdySessionHandler;
public class SpdyPipeLineFactory implements ChannelPipelineFactory{
#Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = pipeline();
pipeline.addLast("decoder", new SpdyFrameDecoder(2));
pipeline.addLast("encoder", new SpdyFrameEncoder(2));
//pipeline.addLast("sessionHandler",new SpdySessionHandler(2,true));
pipeline.addLast("handler", new SpdyChannelUpStreamHandler());
return pipeline;
}
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
public class StartServer {
public static void main(String[] args){
ServerBootstrap bootStrapServer = new ServerBootstrap(new
NioServerSocketChannelFactory(Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
bootStrapServer.setPipelineFactory(new SpdyPipeLineFactory());
bootStrapServer.bind(new InetSocketAddress(8443));
}
}
This is SPDY enabled server example that I was able to put together using netty libraries by reading at multiple places on the internet. When I run this server and Connect using SPDY client ,My connection is successful because I can see the messages in the function that channelOpen and channelConnected.
There are couple questions that I want to ask as I have very limited understanding of SPDY protocol. I will start with the first thing that I want to do.
1 - How can server sends the messages to client , currently I do this in channelConnected method which I can see on the client side , but that gives me very limited chance to send the message and channelConnected event happens once during the Channel Setup process ,
is there any way to get the handle to currently all open channel on SPDY server and identify these channels so that I could select the channels on demand and use them to send the messages?
Your best bet is to create a shared ChannelGroup and whenever a new channel connects, add the channel to the ChannelGroup. You will need to figure out how to identify the channel you want to send to based on the channel meta-data available (such as remote address or channel ID). Then you can retrieve the channel from the ChannelGroup and write messages to it. Additional advantages of the ChannelGroup are
When channels close, they are automatically removed from the ChannelGroup.
You can call close on the ChannelGroup to close all the contained channels.
You can invoke writes on the ChannelGroup to to write a message to all the contained channels.
I wrote an extended Channel wrapper so I can associate additional meta-data to a channel. Part of my protocol is that when a new channel connects, I send it a WHO message and the client responds with some client-identity values which I add to the channel wrapper. I also implemented a JMX interface that exposes the channels in the group so I can see exactly what clients are connected.
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 am setting up a simple TCP Client Server interaction in java.
Server:
The server is a desktop client written in Java:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
class TCPServer
{
public static int PORT_NUMBER = 6129;
public static void main(String argv[]) throws Exception
{
String clientMessage;
ServerSocket welcomeSocket = new ServerSocket(PORT_NUMBER);
while (true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientMessage = inFromClient.readLine();
System.out.println("Received: " + clientMessage);
outToClient.writeBytes("I received this: "+ clientMessage +"\n");
}
}
}
Client:
The client is an android app that connects to the server with TCP. In the client I have a method sendMessage(String msg) which attempts to send a message to the server.
public static void sendMessage(String msg) throws IOException
{
if (mainSocket == null)
{
return;
}
if (!mainSocket.isConnected())
{
connectSocket();
}
PrintWriter output = new PrintWriter( mainSocket.getOutputStream());
output.println(msg);
output.flush();
System.out.println(msg);
}
The problem is, the server receives the first message, but any subsequent messages won't show up at all. When I close the client down, all of a sudden all the other messages show up at once in the server.
This is what the server sees:
Received: message 1
No activity for a long time...
Then I shut down the client
Received: message 2 message 3 message 4 message 5 etc..
I put a println in the sendMessage() method, and the method itself is being called in real time.
You need to explicitly close() your PrintWriter on the client side each time you send a message. Same on the server side when you are done reading inFromClient, and again when you are done writing to outToClient.
See also this basic example, they explain the basic workflow quite nicely:
However, the basics are much the same as they are in this program:
Open a socket.
Open an input stream and output stream to the socket.
Read from and write to the stream according to the server's protocol.
Close the streams.
Close the socket.