GWT XMPP client using GWT-Strophe - gwt

I'm using GWT-Strophe to connect to my XMPP server. Things are going well and I am able to connect to my XMPP server and send other users messages. I'm having a problem with receiving messages. I'm attempting to copy the Strophe echobot example, but the code in my Handler is not getting executed when a message is received.
Here is the code I am using to connect and register the handler:
connection = new Connection("http://localhost/proxy/");
handler = new Handler<Element>() {
#Override
public boolean handle(Element element) {
GWT.log("Handling...");
GWT.log(element.toString());
String to = element.getAttribute("to");
String from = element.getAttribute("from");
String type = element.getAttribute("type");
NodeList<com.google.gwt.dom.client.Element> elems = element.getElementsByTagName("body");
if ((type == null ? "chat" == null : type.equals("chat")) && elems.getLength() > 0) {
Element body = (Element) elems.getItem(0);
GWT.log("ECHOBOT: I got a message from " + from + ": " + body.getText());
String[][] attributes = {{"to", from}, {"from", to}, {"type", "chat"}};
Builder reply = Builder.$msg(attributes).cnode(body.copy());
connection.send(reply.tree());
GWT.log("ECHOBOT: I sent " + from + ": " + body.getText());
}
return true;
}
};
StatusCallback callback = new Connection.StatusCallback() {
#Override
public void statusChanged(Status status, String reason) {
if (status == Status.CONNECTING) {
GWT.log("Strophe is connecting.");
} else if (status == Status.CONNFAIL) {
GWT.log("Strophe failed to connect.");
} else if (status == Status.DISCONNECTING) {
GWT.log("Strophe is disconnecting.");
} else if (status == Status.DISCONNECTED) {
GWT.log("Strophe is disconnected.");
} else if (status == Status.CONNECTED) {
GWT.log("Strophe is connected.");
connection.addHandler(null, null, "message", null, null, handler);
Builder pres = Builder.$pres(null);
connection.send(pres);
GWT.log("ECHOBOT: Send a message to " + connection.getJid() + " to talk to me.");
}
}
};
connection.connect("me#myserver.com", "password", callback);

Change your line
connection.addHandler(null, null, "message", null, null, handler);
with
connection.addHandler(null, "message", null, null, null, handler);
and it should work fine.

Can you post here how you connected gwt-strophe (if you successfully connected)?
Or if you found better solution please post it here. I've made GWT compatible module from gwt-strophe(included gwt.xml and all sources) and used in my GWT project. During compilation there was no error but when i called my widget it says "Cannot read property 'Connection' of undefined". After some code inspection i didn't found where Strophe object is initialized
private native JavaScriptObject connection(String boshService) /*-{
var connection = new $wnd.Strophe.Connection(boshService);
return connection;
}-*/;
Error thrown during runtime execution because window.Strophe object is undefined
p.s. i haven't found here how to add comment so i've made "answer" to ask question in this thread...
All i need is connection from GWT to my openfire server

Related

Can't read/write data (TcpClient/NetworkStream)

A former employees used TCP Client & TCP Listener, Thread, and NetworkStream to create a payment server with Unity 32-bit for Unity 32-bit games and payment connections.
(I don't know what I'm talking about either)
BUT Only the first payment is successful, and the second payment cannot be 'Read' even if it is 'Write'.
(Or maybe client server listener(?) is dumb.... ;( )
So I tried debugging, but this comment came up.
'SocketException System.Net.Sockets.SocketException: Blocking operation aborted by calling WSACanceBlockingCall.'
I can't even connect to the clientServer.
It's fatal to the company that only one payment is made.
This is because after the payment, the game proceeds and when the GameLife is exhausted, you have to return to the lobby and pay again.
But "Write" works, but why doesn't it go on after that?
If you are disconnected from the game and payment server, you will be warned that you are disconnected from the server.
I'm so confused. I'm a client developer and I don't understand anything because I think I'm developing a server.
I'm just a three-month-old junior developer...
This is my client Write Code
public void SendMessage()
{
if (socketConnection == null)
{
return;
}
try
{
// Get a stream object for writing.
NetworkStream stream = socketConnection.GetStream();
if (stream.CanWrite)
{
//string clientMessage = "This is a message from one of your clients.";
string clientMessage = string.Format("Charge,{0}",DataManager.instance.payData._Money);
// Convert string message to byte array.
//byte[] clientMessageAsByteArray = Encoding.ASCII.GetBytes(clientMessage);
byte[] clientMessageAsByteArray = Encoding.UTF8.GetBytes(clientMessage);
// Write byte array to socketConnection stream.
stream.Write(clientMessageAsByteArray, 0, clientMessageAsByteArray.Length);
Debug.Log("Client sent his message - should be received by server");
}
}
catch (SocketException socketException)
{
serverState = ServerState.Disconnect;
Debug.Log("Socket exception: " + socketException);
}
}
This is Server Read Code
private void ListenForIncomingRequests()
{
try
{
// Get Local IPv4 Address
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
address = ip.ToString();
}
}
Debug.Log("address : "+ address);
// Create listener on localhost port 8052.
tcpListener = new TcpListener(IPAddress.Parse(address), 50001);
tcpListener.Start();
Debug.Log("Server is listening");
Byte[] bytes = new Byte[1024];
while (true)
{
using (connectedTcpClient = tcpListener.AcceptTcpClient())
{
Debug.Log(connectedTcpClient.ToString());
// Get a stream object for reading
using (NetworkStream stream = connectedTcpClient.GetStream())
{
int length;
// Read incoming stream into byte arrary.
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0)
{
var incomingData = new byte[length];
Array.Copy(bytes, 0, incomingData, 0, length);
// Convert byte array to string message.
//string clientMessage = Encoding.ASCII.GetString(incomingData);
string[] message = Encoding.UTF8.GetString(incomingData).Split(',');
string clientMessage = message[0];
string value = message[1];
if (string.IsNullOrEmpty(_clientMessage))
{
_clientMessage = clientMessage;
if (_clientMessage.Equals("Charge"))
{
_clientMessage = string.Empty;
pay.PayEvent(int.Parse(value));
}
}
Debug.Log("client message received as: " + clientMessage);
Debug.Log("_client message received as: " + _clientMessage);
Debug.Log(length);
}
}
}
}
}
catch (SocketException socketException)
{
Debug.Log("SocketException " + socketException.ToString());
}
}

How to get all registered user's from xmpp server(openfire) in android

Hi i need to get all registered user from xmpp server(openfire).
try {
UserSearchManager search = new UserSearchManager(connection);
Form searchForm = search.getSearchForm("search."+connection.getServiceName());
Form answerForm = searchForm.createAnswerForm();
answerForm.setAnswer("Username", true);
answerForm.setAnswer("search", "anbu");
ReportedData data = search.getSearchResults(answerForm, "search." + connection.getServiceName());
if (data.getRows() != null) {
Iterator<ReportedData.Row> it = data.getRows();
while (it.hasNext()) {
ReportedData.Row row = it.next();
Iterator iterator = row.getValues("jid");
if (iterator.hasNext()) {
String value = iterator.next().toString();
Log.i("Iteartor values......", " " + value);
}
}
}
} catch (XMPPException e2) {
e2.printStackTrace();
}
I have installed search.jar in admin panel. still i am getting (remote server not found). But chat is working for me.
And why not using the REST API plugin for Openfire?
https://www.igniterealtime.org/projects/openfire/plugins/restapi/readme.html#retrieve-users

Getting Text from IResult Facebook SDK, 7.2.0

I am trying to get the player's username and then display it.
Recently, there was a breaking changes; IResult replacement for FBResult.
I was able to return a texture from the IGraphResult instead of FBResult, to display the profile picture, so I expect that the Text would be available as well but no.
So my issue is, where can I return the Text from?
Do I have to add anything to the IGraphResult?
Here is the code,
void DealWithUserName(FBResult result)
{
if(result.Error != null)
{
Debug.Log ("Problems with getting profile picture");
FB.API ("/me?fields=id,first_name", HttpMethod.GET, DealWithUserName);
return;
}
profile = Util.DeserializeJSONProfile(result.Text);
Text UserMsg = UIFBUsername.GetComponent<Text>();
UserMsg.text = "Hello, " + profile["first_name"];
}
Edited:
Okay, I did it.
It seems that I can also get the username from the IGraphResult.
So, I changed the FBResult to IGraphResult.
I changed result.Text to result.RawResult.
Here is the code, for anyone who needs it.
void DealWithUserName(IGraphResult result)
{
if(result.Error != null)
{
Debug.Log ("Problems with getting profile picture");
FB.API ("/me?fields=id,first_name", HttpMethod.GET, DealWithUserName);
return;
}
profile = Util.DeserializeJSONProfile(result.RawResult);
Text UserMsg = UIFBUsername.GetComponent<Text>();
UserMsg.text = "Hello, " + profile["first_name"];
}
Let's try it
private void DealWithUserName(IGraphResult result){
if (result.ResultDictionary != null) {
foreach (string key in result.ResultDictionary.Keys) {
Debug.Log(key + " : " + result.ResultDictionary[key].ToString());
// first_name : Chris
// id : 12345678901234567
}
}
Text UserName = UIUserName.GetComponent<Text>();
UserName.text = "Hello, "+ result.ResultDictionary["name"].ToString();
}

netty issue when writeAndFlush called from different InboundChannelHandlerAdapter.channelRead

I've got an issue, for which I am unable to post full code (sorry), due to security reasons. The gist of my issue is that I have a ServerBootstrap, created as follows:
bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
final ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
#Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, 3000));
//Adds the MQTT encoder and decoder
ch.pipeline().addLast("decoder", new MyMessageDecoder());
ch.pipeline().addLast("encoder", new MyMessageEncoder());
ch.pipeline().addLast(createMyHandler());
}
}).option(ChannelOption.SO_BACKLOG, 128).option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.SO_KEEPALIVE, true);
// Bind and start to accept incoming connections.
channelFuture = b.bind(listenAddress, listenPort);
With createMyHandlerMethod() that basically returns an extended implementation of ChannelInboundHandlerAdapter
I also have a "client" listener, that listens for incoming connection requests, and is loaded as follows:
final String host = getHost();
final int port = getPort();
nioEventLoopGroup = new NioEventLoopGroup();
bootStrap = new Bootstrap();
bootStrap.group(nioEventLoopGroup);
bootStrap.channel(NioSocketChannel.class);
bootStrap.option(ChannelOption.SO_KEEPALIVE, true);
bootStrap.handler(new ChannelInitializer<SocketChannel>() {
#Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, getKeepAliveInterval()));
ch.pipeline().addAfter("idleStateHandler", "idleEventHandler", new MoquetteIdleTimeoutHandler());
ch.pipeline().addLast("decoder", new MyMessageDecoder());
ch.pipeline().addLast("encoder", new MyMessageEncoder());
ch.pipeline().addLast(MyClientHandler.this);
}
})
.option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.TCP_NODELAY, true);
// Start the client.
try {
channelFuture = bootStrap.connect(host, port).sync();
} catch (InterruptedException e) {
throw new MyException(“Exception”, e);
}
Where MyClientHandler is again a subclassed instance of ChannelInboundHandlerAdapter. Everything works fine, I get messages coming in from the "server" adapter, i process them, and send them back on the same context. And vice-versa for the "client" handler.
The problem happens when I have to (for some messages) proxy them from the server or client handler to other connection. Again, I am very sorry for not being able to post much code, but the gist of it is that I'm calling from:
serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof myProxyingMessage) {
if (ctx.channel().isActive()) {
ctx.channel().writeAndFlush(someOtherMessage);
**getClientHandler().writeAndFlush(myProxyingMessage);**
}
}
}
Now here's the problem: the bolded (client) writeAndFlush - never actually writes the message bytes, it doesn't throw any errors. The ChannelFuture returns all false (success, cancelled, done). And if I sync on it, eventually it times out for other reasons (connection timeout set within my code).
I know I haven't posted all of my code, but I'm hoping that someone has some tips and/or pointers for how to isolate the problem of WHY it is not writing to the client context. I'm not a Netty expert by any stretch, and most of this code was written by someone else. They are both subclassing ChannelInboundHandlerAdapter
Feel free to ask any questions if you have any.
*****EDIT*********
I tried to proxy the request back to a DIFFERENT context/channel (ie, the client channel) using the following test code:
public void proxyPubRec(int messageId) throws MQTTException {
logger.log(logLevel, "proxying PUBREC to context: " + debugContext());
PubRecMessage pubRecMessage = new PubRecMessage();
pubRecMessage.setMessageID(messageId);
pubRecMessage.setRemainingLength(2);
logger.log(logLevel, "pipeline writable flag: " + ctx.pipeline().channel().isWritable());
MyMQTTEncoder encoder = new MyMQTTEncoder();
ByteBuf buff = null;
try {
buff = encoder.encode(pubRecMessage);
ctx.channel().writeAndFlush(buff);
} catch (Throwable t) {
logger.log(Level.SEVERE, "unable to encode PUBREC");
} finally {
if (buff != null) {
buff.release();
}
}
}
public class MyMQTTEncoder extends MQTTEncoder {
public ByteBuf encode(AbstractMessage msg) {
PooledByteBufAllocator allocator = new PooledByteBufAllocator();
ByteBuf buf = allocator.buffer();
try {
super.encode(ctx, msg, buf);
} catch (Throwable t) {
logger.log(Level.SEVERE, "unable to encode PUBREC, " + t.getMessage());
}
return buf;
}
}
But the above at line: ctx.channel().writeAndFlush(buff) is NOT writing to the other channel - any tips/tricks on debugging this sort of issue?
someOtherMessage has to be ByteBuf.
So, take this :
serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof myProxyingMessage) {
if (ctx.channel().isActive()) {
ctx.channel().writeAndFlush(someOtherMessage);
**getClientHandler().writeAndFlush(myProxyingMessage);**
}
}
}
... and replace it with this :
serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof myProxyingMessage) {
if (ctx.channel().isActive()) {
ctx.channel().writeAndFlush(ByteBuf);
**getClientHandler().writeAndFlush(myProxyingMessage);**
}
}
}
Actually, this turned out to be a threading issue. One of my threads was blocked/waiting while other threads were writing to the context and because of this, the writes were buffered and not sent, even with a flush. Problem solved!
Essentially, I put the first message code in an Runnable/Executor thread, which allowed it to run separately so that the second write/response was able to write to the context. There are still potentially some issues with this (in terms of message ordering), but this is not on topic for the original question. Thanks for all your help!

HttpWebRequest maintenance and http web errors causing it to return "HRESULT E_FAIL" and "server not found"

I am iterating through a large list of objects (1503) and calling a save method on a ServiceProxy I have written. The service proxy uses the new networking stack in Silverlight 4 to call BeginGetRequestStream to start the process of asynchronously sending my objects to an azure REST service I have written for saving off the objects. The Http method I am using is POST. I know HttpWebClient is smart enough to reuse the Http connection so I am not concurrently opening 1503 connections to the server. Saving works fine and all 1503 objects are saved very quickly. However, when I try to save the same objects again, I expect to recieve an HttpStatus code of forbidden because the objects already exist and that is the code I set my azure web service to return. On small groups of objects, it works as expected. However, when I try saving the entire list of 1503 objects, I receive only 455 correct responses and 1048 errors such as "server not found" and
System.Exception ---> System.Exception:Error HRESULT E_FAIL has been returned from a call to a COM component.
at
System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)...
I wonder if there is some sort of book keeping or maintenance I am supposed to be performing on my HttpWebClient instances that I am neglecting and that is what is causing the http errors to throw exceptions but the new saves to work perfectly. Here is my code for handling the error cases:
private static void SendAncestorResponseCallback(IAsyncResult result)
{
var info = (SendAncestorInfo)result.AsyncState;
try
{
var response = info.Request.EndGetResponse(result);
info.Response = response;
}
catch ( Exception ex)
{
info.Error = ex;
}
info.MainThreadContext.Post(SendAncestorMainThreadCallback, info);
}
private static void SendAncestorMainThreadCallback(object state)
{
var info = (SendAncestorInfo)state;
IAncestor origAncestor = info.Content;
HttpWebResponse response = null;
if (info.Error != null)
{
if ((info.Error as WebException) == null)
{
info.Callback(false, origAncestor, null, info.Error);
return;
}
else //get response from WebException
{
response = (HttpWebResponse)(info.Error as WebException).Response;
}
}
else //get response from info.Response
{
response = info.Response as HttpWebResponse;
}
if (response.StatusCode == HttpStatusCode.Created || response.StatusCode == HttpStatusCode.Forbidden)
{
var stream = response.GetResponseStream();
using (var reader = new StreamReader(stream))
{
IAncestor retAncestor = XMLSerializerHelper.DeserializeObject<Ancestor>(reader.ReadToEnd());
info.Callback(response.StatusCode == HttpStatusCode.Created, origAncestor, retAncestor, null);
}
}
else info.Callback(false, origAncestor, null, info.Error);
}
considering how the web service is written I should only expect http status codes of created or forbidden and like I said with small groups this is the case. The fact that I only start getting the errors mentioned earlier makes me feel like I am doing something wrong with the HttpWebRequest objects etc. Any assistance would be greatly appreciated. Thanks.
--update here is the code that generates the HttpWebRequest:
foreach (IAncestor ancestor in ancestors)
{
AncestorViewModel ancestorVM = new AncestorViewModel(ancestor);
ancestorVM.Status = SaveStatus.Undefined;
ParsedAncestors.Add(ancestorVM);
_service.CreateAncestor(UserSrc, ancestor, (success, origAncestor, retAncestor, exception) =>
{
AncestorViewModel result = ParsedAncestors.First(a => a.Model.IdNo == origAncestor.IdNo);
if (exception == null)//web response was either Created or Forbidden
{
if (success)//Ancestor successfully created
{
savedAncestors++;
SuccessMessage = string.Format("{0} Saved\n", savedAncestors);
result.Status = SaveStatus.Saved;
}
else //Ancestor already existed
{
conflictAncestors.Add(origAncestor, retAncestor);
ConflictMessage = string.Format("{0} Conflicts\n", conflictAncestors.Count);
result.Status = SaveStatus.Conflicted;
}
}
else //Show exception recieved from remote web service
{
//if (exception as WebException != null)
//{
// //if exception is WebException get status code and description
// HttpWebResponse rs = (HttpWebResponse)(exception as WebException).Response;
// Message += string.Format("WebServer returned status code {0}: '{1}'\n", (int)rs.StatusCode, rs.StatusDescription);
//}
errors.Add(origAncestor, exception);
ErrorMessage = string.Format("{0} Errors\n", errors.Count);
result.Status = SaveStatus.Error;
}
});
}
public void CreateAncestor(string userSrc, IAncestor ancestor, Action<bool, IAncestor, IAncestor, Exception> callback)
{
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
var request = (HttpWebRequest)WebRequest.Create(
new Uri(string.Format("{0}/{1}/{2}", rootUri, AncestorsRestPoint, userSrc)));
request.Method = "POST";
request.ContentType = "application/xml";
var info = new SendAncestorInfo
{
Request = request,
Callback = callback,
Content = ancestor,
MainThreadContext = SynchronizationContext.Current
};
request.BeginGetRequestStream(SendAncestorRequestCallback, info);
}