I have a really huge place in which what I need is that people can chat with each other. I would place WiFi router to cover the whole place but, due to the high amount of people, I can't provide an internet connection through that network. Which technology should I use? I've been reading about AllJoyn but I don't know if that would help me. Also, because of the amount of people (over 75,000) I can't setup a server to handle the service, per connection, 1 devices will have to be the host and the other one will have to be the client. Thanks
If you want to create your own application you could use something like Signalr and Xamarin using their SignalR component.
Taken from the Quick Usage on the component page:
// Connect to the server
var hubConnection = new HubConnection("http://server.com/");
// Create a proxy to the 'ChatHub' SignalR Hub
var chatHubProxy = hubConnection.CreateHubProxy("ChatHub");
// Wire up a handler for the 'UpdateChatMessage' for the server
// to be called on our client
chatHubProxy.On<string>("UpdateChatMessage", message =>
text.Text += string.Format("Received Msg: {0}\r\n", message));
// Start the connection
await hubConnection.Start();
// Invoke the 'UpdateNick' method on the server
await chatHubProxy.Invoke("UpdateNick", "JohnDoe");
Alternatively there are applications out there that likely do what you want already. For example http://beebeep.sourceforge.net/
Related
I am attempting to get Google Nearby API working on my handset (an s5).
I am building and running the stock project from github Google Nearby API GIT.
The app builds and runs, with no errors. Having exported the app onto two S5s (amongst other handsets I have attempted to test it with) and connecting to a WLAN from a D-Link DSL-3680. Multicasting is enabled and set to v3.
However the app refuses to connect with the neighbouring phone when corresponding 'advertise' and 'discover' instructions have been given.
Is there an effective way in which to debug this behaviour? If I can provide an effective information dump of information that might help someone identify the issue then please let me know how.
What do you mean by 'refuse to connect'?
are you getting connection status- 'Rejected'?
If you are able to advertise and discover other devices, I'm assuming all your base conditions (like connected to local network) are fulfilled
Now,
You can try logging your status in Connection call back when you try to connect
Nearby.Connections.sendConnectionRequest(mGoogleApiClient, myName,
remoteEndpointId, myPayload, new Connections.ConnectionResponseCallback() {//response conditions}
using--
inside connection callback function write
if(status.isSuccess()){
// Successful connection
} else {
// Failed connection
}
similarly, if you are not doing this, you need to accept the connection request
Nearby.Connections.acceptConnectionRequest(mGoogleApiClient, remoteEndpointId, myPayload, this)
and inside Onresult callback add-
if(status.isSuccess()){
// Successful connection
} else {
// Failed connection
}
Hope it helped
All the questions here point to classes of the same app or different apps in separate processes yet in the same device. I would like to send data to and from two separate apps in two separate devices. I tried using broadcastreceiver but it didn't work. Here is my snippet to send the data.
addressstring = String.valueOf(acrilocation.getText());
if (addressstring != null && addressstring.length() > 0){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Constants.LOCATION_DATA_EXTRA, addressstring);
intent.setType("text/plain");
sendBroadcast(intent);
} else{
Toast.makeText(getApplicationContext(), "Enter valid location address", Toast.LENGTH_SHORT).show();
}
but when I receive the data in my other app using the following code snippet, It fails. When I debug the app I get null exception.
Intent intent = getIntent();
String action = intent.getAction();
String data = intent.getStringExtra(Intent.EXTRA_INTENT);
String type = intent.getType();
useraddress.setText(data);
startActivity(intent);
Is there another way to achieve this? I mean to send data to and from another app which is installed in another device?
Connecting over networks that accept incoming socket connections
The usual way to do this between Android devices (or between any peer devices) is to use sockets.
You set up one or both devices to 'listen' for connections on a socket and then accept a connection from the other when they want to communicate (or you can have a dedicated client and server and the client always initiates the connections).
Once the connection is established you can send messages back and forth.
There are many examples of Android client server socket applications, but one I found useful was:
Android Server/Client example - client side using Socket (and its companion server side blog article - link included in the client blog)
Note that you may have to add your own 'protocol' on top of this - for example if you are sending a file of unknown length without any special 'end' character, you may want to add a byte (or several byte to represent an int, long etc) at the start to indicate the length of the transmission so the receiving side knows when it has received everything (or that it has not received everything in case of an error).
Connecting over networks which do not allow incoming connections (e.g. most 3G/4G)
In these scenarios, while there is nothing theoretically stopping sockets working, in practice many mobile operators will not allow incoming socket connections. In addition you would need to find the public IP address of the Mobile, which is possible but is extra complexity. If your solution will only ever run on a single operators network you can experiment and see if it works, but if not you may find it better and easier to use a server in the 'middle':
Device A connectes to server
Device B connectes to server
Device A asks server for addresses of connected devices and 'discovers' device B
Device A send a message for device B. It actually sends the messages to the server with an indication that it is to be sent to device B
The server notifies device B that a message is available for it (using some sort of message notification like Google Cloud Messaging for example, or simply by the devices polling regularly to see if they have any messages).
Device B retrieves the messages from the server
The above will work on pretty much any network that allows connectivity to the internet. It does have the disadvantage of requiring a server but it is likely a necessary approach over most mobile networks.
If you want the two instances of your Android app on two different devices located on the different parts of the world to communicate with each other directly without the server, then the best way to do it is to use Tor Hidden Services. Tor Hidden Services allow the apps to bypass the firewall or NAT (if Tor is not blocked, of course), and the devices can easily communicate with each other without the need for a central server. Here, I will try to give some code examples that you can try. The best library suitable to this stuff is this.
Step 1: Add dependencies to your gradle.build in app module:
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
dependencies {
compile 'com.github.jehy:Tor-Onion-Proxy-Library:0.0.7'
compile 'org.slf4j:slf4j-api:1.7.7'
compile 'org.slf4j:slf4j-android:1.7.7'
}
Step 2: Add permissions (Internet permissions or whatever) to your manifest file.
Step 3(i): Now we will just write the classic Client-Server programs in Java but with added Android and Tor flavor. To test this properly, try creating two different apps. One app will be the server and the other app will be a client. Preferably, you can even install the two apps on different phones.
In this example, we will try to send "Hello from Tor client" string from client app to server app.
For the server side: You can try this function inside any Activity and AsyncTask.
void server(Context context){
//For comments and documentation, visit the original repo
//https://github.com/thaliproject/Tor_Onion_Proxy_Library
String fileStorageLocation = "hiddenservicemanager";;
com.msopentech.thali.toronionproxy.OnionProxyManager onionProxyManager =
new com.msopentech.thali.android.toronionproxy.AndroidOnionProxyManager(context, fileStorageLocation);
int totalSecondsPerTorStartup = 4 * 60;
int totalTriesPerTorStartup = 5;
try {
boolean ok = onionProxyManager.startWithRepeat(totalSecondsPerTorStartup, totalTriesPerTorStartup);
if (!ok)
System.out.println("Couldn't start tor");
while (!onionProxyManager.isRunning())
Thread.sleep(90);
System.out.println("Tor initialized on port " + onionProxyManager.getIPv4LocalHostSocksPort());
int hiddenServicePort = 8080;
int localPort = 9343;
String onionAddress = onionProxyManager.publishHiddenService(hiddenServicePort, localPort);
System.out.println("Tor onion address of the server is: "+onionAddress);
ServerSocket serverSocket = new ServerSocket(localPort);
while(true) {
System.out.println("Waiting for client request");
Socket receivedSocket = serverSocket.accept();
ObjectInputStream ois = new ObjectInputStream(receivedSocket.getInputStream());
String message = (String) ois.readObject();
//Here we will print the message received from the client to the console.
/*You may want to modify this function to display the received
string in your View.*/
System.out.println("Message Received: " + message);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
Step 3(ii): For the client side try this function
//Inputs:
//'String onionAddress' should be the one obtained in server() function.
//It will be printed in the console and it will possibly remain the same
//even if the app restarts, because all the data/cache will be stored locally.
//Also, when you run the code for the first time, Tor will take about 1 or 2 mins
//to bootstrap. In the subsequent runs, Tor will start relatively faster as the
//data will be cached. 'int hiddenServicePort' is the port at which the hidden
//service has started on the server. In our example code, it is 8080. So, pass that here
void client(Context context, String onionAddress, int hiddenServicePort){
String fileStorageLocation = "clientmanager";
com.msopentech.thali.toronionproxy.OnionProxyManager onionProxyManager =
new com.msopentech.thali.android.toronionproxy.AndroidOnionProxyManager(context, fileStorageLocation);
int totalSecondsPerTorStartup = 4 * 60;
int totalTriesPerTorStartup = 5;
try {
boolean ok = onionProxyManager.startWithRepeat(totalSecondsPerTorStartup, totalTriesPerTorStartup);
int socksPort=onionProxyManager.getIPv4LocalHostSocksPort();
if (!ok)
System.out.println("Couldn't start tor in client");
while (!onionProxyManager.isRunning())
Thread.sleep(90);
System.out.println("Client Tor initialized on port " + socksPort);
System.out.println("Client is waiting for the server to get ready");
Thread.sleep(2000);
Socket clientSocket =
Utilities.socks4aSocketConnection(onionAddress, hiddenServicePort, "127.0.0.1", socksPort);
ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
oos.writeObject("Hello from Tor client\n");
System.out.println("Client has sent the message");
oos.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
It's done. Run your apps and test it. If you get stuck, try consulting here.
So, now your apps can communicate without any central server. Tor Hidden Services are so awesome in these use cases.
You can also use IP6, then you can do a direct socket connection from one phone to the another. I got latency as low as 60ms between two phones on different 4G operators (in the same country though). Note that you have to send some data to avoid getting down switch to lower speed to get such low latency. 10 concurrent ping was enough for me.
The listen side doesn't need any change at all, the client side just has to use an IP6-address:
s = new Socket("2a10:811:21c:22a1:7683:ae1:18c7:9827", 9343);
IP6 seems to be supported by many operators. If not, tor can be a good fallback, if latency isn't a problem.
I am new to WebRTC native framework.
I was able to get the WebRTC source and run the demo Android application based on http://andrii.sergiienko.me/?go=all/building-webrtc-demo-for-android/enter link description here.
I was able to send/receive Audio and Video between two Android devices on the same local network.
Is there any way to send a small JSON payload in this peer connection?
I tried looking for it in the source and I only found support to send Video and Audio.
Thank you.
Your are looking for WebRTC DataChannels.
WebRTC's RTCDataChannel API is used to transfer data directly from one peer to another. This is great for sending data between two browsers(Peers) for activities like communication, gaming, or file transfer and slew of other functionalities.
It is an Alternative For WebSockets:
This is a great alternative to WebSockets because no central server is involved and transmission is usually faster and there is no bottleneck. You can of course mitigate the failover of P2P transfer by having a hooks which activates Websockets based communication if P2P data-channel communication fails.
Code for Reference:
The events defined are called when you wish to send a message of when a message is received (including error handling). This code should be running in both the browsers. Instead of sending "Hello World" you just need to send your JSON String.
var peerConnection = new RTCPeerConnection();
// Establish your peer connection using your signaling channel here
var dataChannel =
peerConnection.createDataChannel("myLabel", dataChannelOptions);
dataChannel.onerror = function (error) {
console.log("Data Channel Error:", error);
};
dataChannel.onmessage = function (event) {
console.log("Got Data Channel Message:", event.data);
};
dataChannel.onopen = function () {
dataChannel.send("Hello World!");
};
dataChannel.onclose = function () {
console.log("The Data Channel is Closed");
};
The dataChannel object is created from an already established peer connection. It can be created before or after signaling happens. You then pass in a label to distinguish this channel from others and a set of optional configuration settings:
var dataChannelOptions = {
ordered: false, // do not guarantee order
maxRetransmitTime: 3000, // in milliseconds
};
For more details check out the links provided.
Examples:
Link to official documentation: DataChannels in WebRTC
Link to a file Trasfer example using WebRTC Data Channels.
File Transfer
Link to popular Use Cases for WebRTC Data Channels
Use Cases
Lets say there are two android devices and a webpage.
On each of those devices there is a button being clicked and the webpage shows the accumulated clicks.
What makes this possible?
Are the android devices sending that data to a sql database and that counter is reading what currently is in that database?
Or can the device really send the information into the page?
The device can communicate data to the server or to the client side code. You can then have to decide what to do with the data. If you send it to the client side code then it would only update on one device, whereas sending it to the server would allow one click counter across every device.
Changing the page on the server side would add caching problems. So you probably want a data file instead, just a json or something that the server overwrites every time it receives another click.
This isn't very fast though and causes synchronisation issues between the users. For starters for a standard html page the client code is in charge of the calls to the server, so we would have to check the server periodically to see if the value has changed (say every 5 seconds).
A faster alternative would be to use a web socket. The client would keep a connection open to the server and listen for updates from the server, removing the need for our periodic check. Additionally the socket can be used to send clicks to the server and the server can keep the value in its memory removing the need for file writes.
Node.js can be downloaded from http://nodejs.org and this is the plug in I use for web sockets https://github.com/Worlize/WebSocket-Node.
So here is some server side code for a simple web socket server that parrots messages from 1 user to all users, including the user who sent it.
var connections = [];
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
// process HTTP request. Since we're writing just WebSockets server
// we don't have to implement anything.
});
server.listen(1337, function() { });
// create the server
wsServer = new WebSocketServer({
httpServer: server
});
// WebSocket server
wsServer.on('request', function(request) {
//got a new user requesting a connection, so lets accept and store them
var connection = request.accept(null, request.origin);
connections.push(connection);
connection.on('message', function(message) { //inbound message
if (message.type === 'utf8') {
// process WebSocket message
send(message.utf8Data); //bounce to everyone else
console.log(message);
}
});
});
setInterval(function(){console.log(connections.length +" :users");},5000);
//every 5 seconds, tell us how many users we have
function send(message){
var i = connections.length;
while(i--)
connections[i].send(message);
//send the message to all users
}
Example client side
<html><head><script>
var connection, connIsActive = false;
// if user is running mozilla then use it's built-in WebSocket
window.WebSocket = window.WebSocket || window.MozWebSocket;
connection = new WebSocket('ws://127.0.0.1:1337');
connection.onopen = function () {
// connection is opened and ready to use
connIsActive = true;
console.log('Connection loaded');
};
connection.onerror = function (error) {
// an error occurred when sending/receiving data
connIsActive = false
console.log('error');
};
connection.onmessage = function (message) {
// handle incoming message
console.log(message.data);
};
function send(message){
if(connIsActive)connection.send(message);
}
</script></head></html>
Save the first snippet as "myserver.js" (or similar) and start it up in node via command line. Save the second snippet as a "client.html" and open it on 2 devices, or just 2 browser instances. Theres no interface on the client but you can send and receive messages from the debug console using send("message string")
Provided you can wrap your head around my snippets, modifying it to work like your example should prove fairly easy!
To achieve what you are trying to do, you need to learn socket programming for android.
In order to use two device(clients) you also need to learn port forwarding for servers.
To begin try this tutorial.
I need to trnasfer data from one android device to another device over wifi network?
If one device is willing to perform access-point like functionality as part of a portable hotspot, and you select that as a wirelss network on the other, you may achieve a network connection between the two that can be used for custom traffic. Though there are ways the hotspot could be implemented where that would not work. Also of concern, the "client" device will now be sending all of its network traffic through the hotspot device, including not just foreground apps but anything it decides to do in the background.
First you need to know to which device you want to transfer the data over network like to mobile device to pc. Suppose you are trying to send data you need will a continuous socket connection using a thread ... the back end device should accept the socket connection and accept the stream....
consider the frist device as client which will write the stream
Runnable action = new Runnable() {
public void run() {
//create your connection
while (true){
//write your stream here
}
}
};
new Thread(action).start();
and server side the device will open the stream and read it continuously
now in the write your stream code use link the and integrate like the example
Click here!