Connecting Unity client to XMPP server - unity3d

I'm trying to make a client for chat using unity.
I have found this library https://github.com/bilelmnasser/Unity-3D-Xmpp-Protocol-
so I've imported to my project and being testing the code but I can't seem to get it to work.
using UnityEngine;
using Xmpp;
using Xmpp.protocol.client;
public class NewBehaviourScript : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
var xmppClient = new XmppClientConnection("localhost");
//xmppClient.ConnectServer = "ipServer";
xmppClient.Server = "localhost";
xmppClient.Port = 5222;
xmppClient.Username = "admin#localhost";
xmppClient.Password = "password";
xmppClient.Open();
xmppClient.OnLogin += delegate(object o) { xmppClient.Send(new Message("user#localhost", MessageType.chat, "Hello, how are you?")); };
}
Here is my code. I have a ejabberd server running using docker.
I've created two users and tested on node server as client and it worked fine, but can't get to work on unity...
any help would be great!

Related

Connect MQTTnet with Azure IoT Hub

I have created a device that delivers messages. Now I want to send them to an Azure IoT Hub by using MQTTnet Version 2.4.0 because the .NET target Framework is on Version 4.5 and it is not my decision to change it.
My Question:
Is there any other or better method to do this
What MqttClientOption do I take best
What Parameters to set to which value to connect to the Hub
I have tried almost every combination of values for the ClientId/UserName/Password as described here: https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support#using-the-mqtt-protocol-directly-as-a-device
but none of them worked for me
I have tried outside the Project and build a similar device on the current framework and it worked perfectly with the newer version of MQTTnet.
Sadly I don't get any kind of error message only a MqttCommunicationTimedOutException after about 10 seconds.
Thanks for your help I have been stuck at this problem for almost a week.
The following code snippet is a working example of the simulated device1 using the MQTT protocol directly to the Azure IoT Hub via the MQTTnet Version 2.4.0 library:
using MQTTnet;
using MQTTnet.Core;
using MQTTnet.Core.Client;
using MQTTnet.Core.Packets;
using MQTTnet.Core.Protocol;
using System;
using System.Text;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var options = new MqttClientTcpOptions()
{
Server = "myIoTHub.azure-devices.net",
Port = 8883,
ClientId = "device1",
UserName = "myIoTHub.azure-devices.net/device1/api-version=2018-06-30",
Password = "SharedAccessSignature sr=myIoTHub.azure-devices.net%2Fdevices%2Fdevice1&sig=****&se=1592830262",
ProtocolVersion = MQTTnet.Core.Serializer.MqttProtocolVersion.V311,
TlsOptions = new MqttClientTlsOptions() { UseTls = true },
CleanSession = true
};
var factory = new MqttClientFactory();
var mqttClient = factory.CreateMqttClient();
// handlers
mqttClient.Connected += delegate (object sender, EventArgs e)
{
Console.WriteLine("Connected");
};
mqttClient.Disconnected += delegate (object sender, EventArgs e)
{
Console.WriteLine("Disconnected");
};
mqttClient.ApplicationMessageReceived += delegate (object sender, MqttApplicationMessageReceivedEventArgs e)
{
Console.WriteLine(Encoding.ASCII.GetString(e.ApplicationMessage.Payload));
};
mqttClient.ConnectAsync(options).Wait();
// subscribe on the topics
var topicFilters = new[] {
new TopicFilter("devices/device1/messages/devicebound/#", MqttQualityOfServiceLevel.AtLeastOnce),
new TopicFilter("$iothub/twin/PATCH/properties/desired/#", MqttQualityOfServiceLevel.AtLeastOnce),
new TopicFilter("$iothub/methods/POST/#", MqttQualityOfServiceLevel.AtLeastOnce)
};
mqttClient.SubscribeAsync(topicFilters).Wait();
// publish message
var topic = $"devices/device1/messages/events/$.ct=application%2Fjson&$.ce=utf-8";
var payload = Encoding.ASCII.GetBytes("Hello IoT Hub");
var message = new MqttApplicationMessage(topic, payload, MqttQualityOfServiceLevel.AtLeastOnce, false);
mqttClient.PublishAsync(message);
Console.Read();
}
}
}
and the following screen snippet shows an example of the output for updating a desired twin property color and receiving a C2D message:

Connection not working from Android to UWP on desktop - ZeroMq (NetMq)

I tried some examples of ZMQ on C++,C# and Python. I am trying to have Request-Reply pattern to connect Android device to PC running UWP with Xamarin forms.
Below is the Requestor code:
public void HelloWorld()
{
var timer = new Timer(60000);
timer.Start();
timer.Elapsed += (sender, args) =>
{
this.Cancel = true;
timer.Stop();
};
// Create
const string endpoint = "tcp://PC_ip:3245";
using (var request = new RequestSocket())
{
request.Bind(endpoint);
Thread.Sleep(2000);
while (!Cancel)
{
request.SendFrame("Requester says hello");
var reply = request.ReceiveFrameString();
Debug.WriteLine("Gets reply {0}",reply);
}
}
}
Reply socket code:
public void HelloWorld()
{
var timer = new Timer(60000);
const string endpoint = "tcp://PC_ip:3245";
timer.Start();
timer.Elapsed += (sender, args) =>
{
timer.Stop();
Cancel = true;
};
using (var replierSocket = new ResponseSocket())
{
replierSocket.Connect(endpoint);
Thread.Sleep(2000);
while (!Cancel)
{
var replyFromRequester = replierSocket.ReceiveFrameString();
Debug.WriteLine("Got reply {0}", replyFromRequester);
replierSocket.SendFrame("Response socket say hello");
}
}
}
Cancel is boolean
I went through some questions posted on this and added delay and these connection code blocks only trigger after button clicks on app.
While debugging , request.ReceiveFrameString() replierSocket.ReceiveFrameString(); are not even hit.
I am new to network programming , I understand that for REQ/REP pattern the code has to be in particular order which I traced and fixed I believe and turned off firewall on my PC so that firewall wont block my incoming connections from Android device.
PC_ip stands for IPv4 address I got from ipconfig /all for my wifi. I also tried external ip of my machine from sites like whatsmyip.org at ResponseSocket but I still dont get response between devices.
Please let me know what am I doing wrong.
Issue replication repository : GitHub/me/XamZeroMq

SignalR Core with Redis Pub\Sub and console application

I am having Asp.Net Core 2.1 with SignalR Core 1.0.1.
I have created chat application that is described here:
https://learn.microsoft.com/en-us/aspnet/core/tutorials/signalr?view=aspnetcore-2.1&tabs=visual-studio
Also have configured SignalR to use Redis using
services.AddSignalR().AddRedis(Configuration["ConnectionStrings:Redis"]);
Having running Redis server up with redis-cli monitor I can see the following commands coming:
1530086417.413730 [0 127.0.0.1:57436] "SUBSCRIBE" "SignalRCore.Hubs.ChatHub:connection:VAIbFqtNyPVaod18jmm_Aw"
1530086428.181854 [0 127.0.0.1:57435] "PUBLISH" "SignalRCore.Hubs.ChatHub:all" "\x92\x90\x81\xa4json\xc4W{\"type\":1,\"target\":\"ReceiveMessage\",\"arguments\":[{\"user\":\"user\",\"message\":\"message\"}]}\x1e"
Everything works fine till the time when I would like to push some message from another console application.
In that application I am using ServiceStack.Redis and the code is the following:
var redisManager = new RedisManagerPool(configuration["ConnectionStrings:Redis"]);
using (var client = redisManager.GetClient())
{
client.PublishMessage("SignalRCore.Hubs.ChatHub:all", "{\"type\":1,\"target\":\"ReceiveMessage\",\"arguments\":[{\"user\":\"FromConsole\",\"message\":\"Message\"}]");
}
The messages are not handled by browser. I assume the case is in this additional information that is used for SignalR:
"\x92\x90\x81\xa4json\xc4W{...}\x1e"
Related monitor record:
1530087843.512083 [0 127.0.0.1:49480] "PUBLISH" "SignalRCore.Hubs.ChatHub:all" "{\"type\":1,\"target\":\"ReceiveMessage\",\"arguments\":[{\"user\":\"FromConsole\",\"message\":\"Message\"}]"
Any ideas how can I specify this additional data for publish?
Probably I should use something more suitable for my case instead of ServiceStack.Redis
using Microsoft.AspNetCore.SignalR.Protocol;
using Microsoft.AspNetCore.SignalR.Redis.Internal;
using StackExchange.Redis;
using System.Collections.Generic;
static void Main(string[] args)
{
using (var redis = ConnectionMultiplexer.Connect("127.0.0.1:6379"))
{
var sub = redis.GetSubscriber();
var protocol = new JsonHubProtocol();
var redisProtocol = new RedisProtocol(new List<JsonHubProtocol>() { protocol});
var bytes = redisProtocol.WriteInvocation("ReceiveMessage", new[] { "60344", "60344" });
sub.Publish("SignalRChat.Hubs.ChatHub:all", bytes);
}
}
How to find it?
in signalr source code search ".Publish", you can find the https://github.com/aspnet/SignalR/blob/c852bdcc332ffb998ec6a5b226e35d5e74d24009/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisHubLifetimeManager.cs
it uses the RedisProtocol and messagepack to .WriteBytes. header footer name count...

How to make sockets work in xamarin?

In the Answer to this question Here:Server Client Application with .NET and Xamarin
the person who answered said: "On Xamarin.Android you can use all of the regular .Net socket classes"
I tried using the code in example of the Microsoft documentation and i had no errors but application just is just displaying like that on the phone:
If I delete the socket code it would display the page normally.My code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Net;
using System.Net.Sockets;
namespace App14
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Page2 : ContentPage
{
public static string data = null;
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
while (true)
{
var label = new Label() { Text = "searching for a connection" };
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
label.Text = "Found a Connection";
data = null;
// An incoming connection needs to be processed.
while (true)
{
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf("<EOF>") > -1)
{
break;
}
}
// Show the data on the console.
label.Text = "Text received" + data;
// Echo the data back to the client.
byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public Page2 ()
{
StartListening();
Title = "Sign in page";
InitializeComponent();
}
private void page2_click(object sender,EventArgs e)
{
Navigation.PushAsync(new Page1(), true);
}
}
}
Xaml File code:
Why is this?.and can you please provide an example of client mobile or server mobile socket
You are blocking the UI Thread with your StartListening call, since it has a infinite while loop.
The label you create in the while loop is never added as content on the page. Hence the text you add to it will never be shown. You already have a label defined with the name l on the page. In this case you could just use that to add text:
l.Text = "hello";
As commented, you should start your socket listening code on another thread to not block you UI. This could be as simple as writing Task.Run(() => StartListening());. Make sure you understand what this does and possibly how you cancel this Task again when navigating away from the page or during App lifecycle.
If you try to Connect from your mobile with the correct ip address and port number of the Listener when both devices are in the same LAN it should work. If one of the devices is behind a different LAN router/modem you won't be able to connect because the router will block all incoming connections unless you use a port routing mechanism like UPnP.

Matlab can not read the socket for the second time

I want to communicate between two programs. MATLAB is able to read the socket once but when it tries to read it again, I get the following warning
Warning: Unsuccessful read: A timeout occurred before the Terminator was reached.
Matlab code:
clc
clear all
while(1)
clear tcpipServer
tcpipServer = tcpip('127.0.0.1', 55000, 'NetworkRole', 'Server');
set(tcpipServer, 'Timeout', 30);
fopen(tcpipServer);
rawData = fgetl(tcpipServer);
fclose(tcpipServer);
end
The data which is sent to Matlab is defined as string and the value is "y\n".
The problem is that I only receive "y\n" once.
The other side connected to the socket is the Unity game engine. I think the code in the unity is correct because I tested that by c# windows app and I can get the value as long as program is running.
Does anyone know why this is happening?
This is the solution i found.
Matlab code:
clc
clear all
%% server initialization
tcpipServer = tcpip('127.0.0.1',55000,'NetworkRole','Server');
set(tcpipServer,'Timeout',30);
while(1)
%% server code: listening for incoming requests
fopen(tcpipServer);
%rawData = fread(tcpipServer,1,'char');
rawData = fgetl(tcpipServer)
extractedData=str2double(strsplit(rawData,'-'))
fclose(tcpipServer);
Unity C# code:
using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Linq;
using System;
using System.IO;
using System.Text;
public class server : MonoBehaviour {
// Use this for initialization
TcpListener listener;
String msg;
StreamWriter theWriter1;
internal Boolean socketReady = false;
TcpClient mySocket;
NetworkStream theStream;
StreamWriter theWriter;
StreamReader theReader;
String Host = "localhost";
Int32 Port = 55000;
bool firstTimeRun=true;
void Start () {
}
// Update is called once per frame
void Update () {
setupSocket ();
if (Input.GetMouseButtonDown (0))
{
setupSocket ();
}
}
public void setupSocket() {
try {
TcpClient mySocket1;
NetworkStream theStream1;
//StreamWriter theWriter1;
mySocket1 = new TcpClient(Host, Port);
theStream1 = mySocket1.GetStream();
theWriter1 = new StreamWriter(theStream1);
Invoke("write", 0.2f);
}
catch (Exception e) {
Debug.Log("Socket error: " + e);
}
}
void write()
{
float x;float y;
x = GameObject.FindGameObjectWithTag ("Player").transform.position.x;
y=GameObject.FindGameObjectWithTag ("Player").transform.position.y;
theWriter1.Write(x+"-"+y+"\n");
theWriter1.Flush();
}
The reason I used "\n" is using fgetl function in Matlab code. if you want to make the code more functional use delay along with Asynchronous tasks in Unity. for those wandering why using delay is required, see the comments under question.