TcpIp communication from an Azure Function? - azure

I have an azure Queue trigger function that has this code:
using (var client = new TcpClient(AddressFamily.InterNetworkV6))
{
client.Client.DualMode = true;
client.Connect(endpoint);
var data = Encoding.ASCII.GetBytes("test");
using (var outStream = client.GetStream())
{
outStream.Write(data, 0, data.Length);
}
}
The error I am getting back:
A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection
failed because connected host has failed to respond
The endpoint address looks correct and this code works when I debug locally, so I suspect that the azure server might not be allowing the outbound connection.
Any ideas why this connection is not working?
Update: This is still not working and I have tried generating the client in the following ways:
// DualMode IPV6
var client = new TcpClient(AddressFamily.InterNetworkV6);
client.Client.DualMode = true;
client.Connect(endpoint);
// SingleMode Internetwork
var client = new TcpClient(AddressFamily.InterNetwork);
client.Connect(endpoint);
// Just Endpoint
var client = new TcpClient(endpoint);
client.Connect(endpoint);
// Normal
var client = new TcpClient(hostAddress, port);
// Forced IPV6
var client = new TcpClient("::ffff:" + hostAddress, port);
Debugging locally, all of these methods except for "forced IPV6" work just fine. On the server, I get these errors:
== DualMode IPV6
Failed PingBack: A connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed because connected host
has failed to respond [::ffff:204.16.184.62]:3164
== SingleMode Internetwork
Failed PingBack: A connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed because connected host
has failed to respond 204.16.184.62:3164
== Just Endpoint
Failed PingBack: The requested address is not valid in its context
== Normal
Failed PingBack: A connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed because connected host
has failed to respond 204.16.184.62:3164
== Forced IPV6
Failed PingBack: The requested address is not valid in its context [::ffff:204.16.184.62]:3164

Looking at your TcpClient instance,
var client = new TcpClient(AddressFamily.InterNetworkV6)
there's no IPv6 in Azure Functions yet. Switch your AddressFamily to v4:
var client = new TcpClient(AddressFamily.InterNetwork)
There are no restrictions on outbound desinations in App Service/Functions.

Related

SMPP server - How to get the client (ESME's) IP address?

I'm using https://github.com/farhadi/node-smpp in order to create a smpp server.
I'm going to forbid connection if the client's IP address is not in the allowed ips list. For that when a new connection is open I have to check if the credentials are ok and if the IP address is a good one.
The question is how and where can I get the client (ESME's) IP address?
session.on('bind_transceiver', function(pdu) {
session.pause();
const username = pdu.system_id;
const password = pdu.password;
const ipAddress = ''; // WHERE TO GET IT??
if (credentialsAreOk(username, password, ipAddress)) {
session.send(pdu.response());
session.resume();
} else {
session.close();
}
});
When an ESME is connecting to your server, a session is created.
The network socket used by this TCP connection, which is a net.Socket class (https://nodejs.org/api/net.html#net_class_net_socket), is stored inside this session in the socket property.
const socket = session.socket;
So you can easily access this socket property of the session and get the remoteAddress (the clients IP) from there (https://nodejs.org/api/net.html#net_socket_remoteaddress).
const ipAddress = session.socket.remoteAddress;

Using go with redis - not able to connect

I'm trying to connect to Redis service in azure
I use the following code:
import (
"fmt"
"os"
"github.com/go-redis/redis"
)
func main() {
uri := os.Getenv("uri")
fmt.Println("uri is", uri)
opt, err := redis.ParseURL(uri)
if err != nil {
fmt.Println(err)
}
fmt.Println("addr is:”, opt.Addr)
fmt.Println("db is:”, opt.DB)
fmt.Println("password is:”, opt.Password)
//connect to redis
client = redis.NewClient(opt)
//Here I want to get connection
pong, err := client.Ping().Result()
https://github.com/go-redis/redis
https://godoc.org/github.com/go-redis/redis#example-ParseURL
The printed data is like following I was able to the the connection string
uri is rediss://:bBMfQ7wFdkPHr8u%2B2zzNOzUpy85OEjYv7KbPZd8B89M%3D#e49ab3c6-8f72-416a-a6c1-ddfe75gf200e.redis.cache.windows.net:6380
addr is: e49ab3c6-8f72-416a-a6c1-ddfe75gf200e.redis.cache.windows.net:6380
db is: 0
password is: bBMfQ7wFdkPHr8u+2zzNOzUpy85OEjYv7KbPZd8B89M=
The Redis service is up and running and I was able to connect with nodejs application and get the data, any idea why I got the error in go:
dial tcp 40.128.8.87:6380: connect: connection refused
We are trying to migrate some apps from Nodejs to go ...
The strange thing is that in nodejs I use the following which works!
https://github.com/NodeRedis/node-redis
const redisClient = redis.createClient(process.env.uri);
redisClient.on("connect", () => console.log("Redis is connected"));
update
I've provisioned a new instance without ssl which is not working either
This is the logs
uri is redis://:TKq1n%2BO29jsSdIkoysXL%2Btwd6Xi0IO0KNxw%3D#2dca2dx1-20e0-48ca-83ed-20bf52e99b97.redis.cache.windows.net:6379
addr is 2dca2dx1-20e0-48ca-83ed-20bf52e99b97.redis.cache.windows.net:6379
db is 0
password is TKq1n+O29jsSdIkoysXL+twd6Xi0IO0KNxw=
dial tcp 40.113.7.3:6379: connect: connection refused
Any idea how should I use the GO api to connect to redis properly ?
Btw, when I connected to local Redis it works, but not to azure cache
like this
client := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
Maybe I miss something in the Redis api, as I do the same (connect to the same service instance ) for nodejs and it works!

node net.createServer get connection path

Trying to cluster Socket.io using net.createServer. All examples are using IP to split what connection goes to witch node. However I'm using 4 servers with a load balancer that points ip;s to the different servers.
So in node cluster I would like to use an unique id to point the connection to a specific cluster.
Figure that each user that wants to connect can add a parameter to the connection url ws://localhost/socket.io?id=xxyyzz
How can I get the connection url in net.createServer
todays code for ip:
var server = net.createServer({ pauseOnConnect: true }, function(connection) {
// We received a connection and need to pass it to the appropriate
// worker. Get the worker for this connection's source IP and pass
// it the connection.
var remote = connection.remoteAddress;
var local = connection.localAddress;
var ip = (remote+local).match( /[0-9]+/g )[0].replace(/,/g, '');
var wIndex = ip % num_processes;
var worker = workers[wIndex];
worker.send('sticky-session:connection', connection);
});

How to create TCP client in C# that can recover from server disconnect

I am building a TCP client application in C#. It connects to a server. Under normal conditions the server sends out new data every second. My client application parses the byte stream, saves it to the database and then waits for the next message from the server. It runs on a separate thread and should continue receiving messages and processing them as long as the main application is running. However there may be times where the server goes away or the network connection is temporarily lost, etc. My code needs to be able to recover from that and continue processing server messages if the server comes back online or is again reachable. My current code seems to hang when the server is disconnected and the only way to get it to process again is to shut it down completely and then restart it. What am I doing wrong?
bool IsCancelled = false;
IPEndPoint _ipEndPoint = new IPEndPoint(IPAddress.Parse(myIPAddress), myPort);
TCPClient _tcpClient = new TCPClient();
_tcpClient.Connect(_ipEndPoint);
NetworkStream _networkStream = _tcpClient.GetStream();
while(!IsCancelled)
{
_data = new byte[10025];
if(_networkStream.CanRead)
{
_bytesRead = _networkStream.Read(_data, 0, (int)_tcpClient.ReceiveBufferSize);
if(_bytesRead > 0)
{
...Process data...
}
}
}

How make a multi client server using Bluetooth API in j2me?

I am planning to implement a server using Bluetooth API using J2ME. I want multiple clients to be able to connect to it at the same time but I could not find much on the NET.
UUID uuid = new UUID("1101", false);
String SurveyAnswer="";
//Create the service url
String connectionString = "btspp://localhost:" + uuid + ";name=xyz";
//open server url
StreamConnectionNotifier streamConnNotifier = (StreamConnectionNotifier) Connector.open(connectionString);
//Wait for client connection
System.out.println("\nServer Started. Waiting for clients to connect...");
while(true){
StreamConnection connection = streamConnNotifier.acceptAndOpen();
}
How do I modify these codes in order for it to work as a multi client server?
That's a standard problem. When the StreamConnection connection = streamConnNotifier.acceptAndOpen(); returns you have to spawn a Thread which uses the connection. The main Thread then reenters the accept and waits for next connection.
UUID uuid = new UUID("1101", false); String SurveyAnswer="";
//Create the service url
String connectionString = "btspp://localhost:" + uuid + ";name=xyz";
//open server url
StreamConnectionNotifier streamConnNotifier = (StreamConnectionNotifier)
Connector.open(connectionString);
//Wait for client connection
System.out.println("\nServer Started. Waiting for clients to connect...");
while(true){
StreamConnection connection = streamConnNotifier.acceptAndOpen();
System.out.println("Client connected starting communication");
new CommunicationThread(connection).start();
}
In the class CommunicationThreads run method you can then get the streams and communicate.

Resources