Description
So basically i am building an android app in which i am using kotlin and which will behave as server.Whilst on the client side i am using python.I am using sockets for this purpose.I have to communicate using UDP.But i am unable to make connection to my android app.In python script sock.connect(('10.0.2.2', 6000)) i have also tried placing the emulator ip instead of localhost.I just want to send and receive simple messages.
Another Issue: Python script just times out it does not even gets into the loop.
Server.kt
package com.example.soundsource
import android.content.Intent
import android.os.AsyncTask
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import java.io.BufferedInputStream
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.lang.Exception
import java.lang.ref.WeakReference
import java.net.ServerSocket
import java.net.Socket
class MainActivity : AppCompatActivity() {
private lateinit var textView:TextView
private var message = " "
private lateinit var client:Socket
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sendButton:Button = findViewById(R.id.send_button)
val showLocation = findViewById(R.id.show_location) as? Button
showLocation?.setOnClickListener {
val intent = Intent(this,SoundLocation::class.java)
startActivity(intent)
}
textView = findViewById(R.id.text_view)
sendButton.setOnClickListener{
t.start()
}
}
private val t = Thread(Runnable {
val port = 5000
val server = ServerSocket(port)
this.message = "Message from client"
this#MainActivity.runOnUiThread {
this.textView.text = server.localPort.toString()
}
val i = InputStreamReader(this.client.getInputStream())
val b = BufferedReader(i)
while (true){
this.client = server.accept()
message += " "+ this.client.localAddress.toString()+b.readLine()
this#MainActivity.runOnUiThread{
this.textView.text = server.localSocketAddress.toString()
}
t2.start()
}
})
private val t2 = Thread(Runnable {
val p = PrintWriter(this.client.getOutputStream())
p.println("sending message back")
runOnUiThread {
this.textView.text = "message sent...."
}
})
}
Client.py
import socket
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('10.0.2.2', 5000))
while True:
print("you are about to.....")
data = sock.recv(1024)
print('you received :', data)
sock.sendall(bytes("hey kotlin....", 'utf-8'))
main()
I saw that this problem is quite common, but I couldn't figure it out how to solve it in my case.
I'm creating a server in Python like this:
clients = []
server = None
class SimpleWSServer(WebSocket):
def handleConnected(self):
clients.append(self)
def handleClose(self):
clients.remove(self)
def run_server():
global server
server = SimpleWebSocketServer('', 9000, SimpleWSServer,
selectInterval=(1000.0 / 15) / 1000)
server.serveforever()
t=threading.Thread(target=run_server)
t.start()
if( ...)
for client in clients:
msg = json.dumps({'x': cX, 'y': cY})
client.sendMessage(unicode(msg))
and I'm open a WebSocket using three.js in this way:
var ws = new WebSocket('ws://192.168.0.15:9000/');
ws.onopen = function() {
console.log('onopen');
};
ws.onmessage = function (event) {
var m = JSON.parse(event.data);
history.push({ x: m.x * 2 - 1, y: -m.y * 2 + 1});
window.alert("X: "+x + " Y "+ y)
// ... rest of the function.
};
The localhost server is created using node.js and I don't have any errors in the log, meanwhile in Google Chrome I have the error: " threejs_prova.js:3 WebSocket connection to 'ws://192.168.0.15:9000/' failed: Connection closed before receiving a handshake response"
Error in Firefox is:
Firefox can't connect to server ws://192.168.0.15:9000/
In my case changing
var ws = new WebSocket('ws://192.168.0.15:9000/');
with
var ws = new WebSocket('ws://localhost:9000/');
solved the problem
How do I send a server a struct?
I tried:
import socket
import sys
import capnp
import select
import test_capnp
class Test:
def __init__(self, serverAddr="127.0.0.1", serverPort = 10000):
self.serverAddress = (serverAddr, serverPort)
capnp.remove_import_hook()
self.setupClient()
def setupClient(self):
_socket = socket.socket()
_socket.connect(self.serverAddress)
client = capnp.TwoPartyClient(_socket)
send = client.bootstrap().cast_as(capnp._DynamicCapabilityClient(test_capnp))
Test.capnp:
struct Test {
id #0 : UInt8;
msg #1 : Text;
}
Furthermore, how can I give values to the Test?
Thanks for helping :)
lol have you proceed to the second turn of the competition?
I have an accelerometer in my tablet, that I can read from within javascript.
How can I access this data in python? Is there some ctypes trickery I can use to call a windows 8 Sensor API function?
Horrible hack - start up a webserver in server.py:
import bottle
from threading import Thread
on_data = lambda alpha, beta, gamma: None
#bottle.route('/')
def handler():
return bottle.static_file('index.html', '.')
#bottle.post('/data')
def handler():
on_data(**bottle.request.json)
def data_handler(f):
global on_data
on_data = f
return f
def go():
t = Thread(target=lambda: bottle.run(quiet=True))
t.start()
With this index.html:
<script>
window.addEventListener('deviceorientation', function(eventData) {
var d = {};
['alpha', 'beta', 'gamma'].forEach(function(prop) {
d[prop] = eventData[prop];
})
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:8080/data");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(JSON.stringify(d));
}, false);
</script>
And use it as:
import server
#server.data_hander
def on_acc_data(alpha, beta, gamma):
print alpha, beta, gamma
server.go()
After having opened localhost:8080/ in the browser
I need to receive data from device connected via Ethernet (modbus/TCP) and send it to webpage (maybe using web sockets).
I can't find good examples. Now I can connect with driver and print values using ModbusClientProtocol.read_input_registers() but I had to create own factory and protocol class. I am using autobahn, twisted, pymodbus.
I've no familiarity with modbus or pymodbus, so I'm guessing and leaving a lot of blanks for you to fill in.
This is hacked out of something I recently put together to receive snmptraps and redistribute the information to connected websockets.
Hopefully this is enough to get you going:
#!/usr/bin/python
from twisted.internet import protocol, reactor, utils, defer
from twisted.web.server import Site
from twisted.web.static import File
from autobahn.websocket import WebSocketServerFactory, WebSocketServerProtocol
from autobahn.util import newid
from autobahn.resource import WebSocketResource
class ModbusThing(object):
def __init__(self,clientAddress):
self.clientAddress = clientAddress
self.client = None
def start(self):
pass
## Create client connection to modbus server
## Start Looping Call of pollForData with suitable interval
def pollForData(self):
pass
## Call read methods on ModbusClient object, add call backs to process the results
## Add errorBacks to notify of errors
def resultCallback(self,result):
pass
## Process the data from a read request
## Assumes that your websocket clients expect json like {"event":"update","data":[0,1,2]}
message = dict(event="update",data=processedResults)
self.broadcast(json.dumps(message))
def broadcast(self,msg):
"""Override me"""
pass
class TrackingWebSocketProtocol(WebSocketServerProtocol):
def onOpen(self):
self.session_id = newid()
self.factory._addSession(self,self.session_id)
print "Socket Open %s" % (self.peerstr,)
def onMessage(self,payload,isBinary):
print "Message received from %s\n\t: %r" % (self.peerstr,payload)
def onClose(self,wasClean,code,reason):
self.factory._removeSession(self)
print "Socket Closed %s" % (self.peerstr,)
class TrackingWebSocketFactory(WebSocketServerFactory):
def __init__(self,*args,**kwargs):
WebSocketServerFactory.__init__(self,*args,**kwargs)
self.proto2session = {}
self.session2proto = {}
def _addSession(self,proto,session_id):
if not self.proto2session.has_key(proto):
self.proto2session[proto] = session_id
else:
raise Exception("logic error - dublicate _addSession for protoToSessions")
if not self.session2proto.has_key(session_id):
self.session2proto[session_id] = proto
else:
raise Exception("logic error - dublicate _addSession for sessionsToProto")
def _removeSession(self,proto):
if proto in self.proto2session:
session_id = self.proto2session[proto]
del self.proto2session[proto]
if session_id in self.session2proto:
del self.session2proto[session_id]
def sendToAll(self,message,binary=False):
prepped = self.prepareMessage(message,binary)
for proto in self.proto2session.keys():
proto.sendPreparedMessage(prepped)
def run():
## WebSocket Factory
wsfactory = TrackingWebSocketFactory('ws://yourhostname:80')
wsfactory.protocol = TrackingWebSocketProtocol
wsresource = WebSocketResource(wsfactory)
## Modbus handler
modbus_thing = ModbusThing((addressofserver,portofserver))
modbus_thing.broadcast = wsfactory.sendToAll
modbus_thing.start()
## WebServer Site
# "static" subdirectory, containing http served resources, e.g. index.html, javascript and css
root = File("static")
# Your websocket service as 'ws://yourhostname/ws'
root.putChild("ws", wsresource)
site = Site(root)
reactor.listenTCP(80,site)
def main():
reactor.callWhenRunning(run)
reactor.run()
if __name__=='__main__':
main()
On the browser side of things. A little module for interacting with websockets is handy:
var FancyWebSocket = function(url){
var conn = null;
var fws = this;
if ("WebSocket" in window) {
conn = new WebSocket(url);
} else if ("MozWebSocket" in window) {
conn = new MozWebSocket(url);
} else {
console.log("Error Websockets not supported in browser");
return;
}
var callbacks = {};
var debug = true;
this.bind = function(event_name, callback){
callbacks[event_name] = callbacks[event_name] || [];
callbacks[event_name].push(callback);
return this;// chainable
};
this.send = function(event_name, event_data){
var payload = JSON.stringify({event:event_name, data: event_data});
conn.send( payload ); // <= send JSON data to socket server
return this;
};
this.close = function(){ conn.close(); return this;}
// dispatch to the right handlers
conn.onmessage = function(evt){
if (debug) console.log("Websocket(" + conn.URL + ") Message: " + evt.data)
var json = JSON.parse(evt.data)
dispatch(json.event, json.data)
};
conn.onclose = function(){
if (debug) console.log("Websocket(" + conn.URL + ") Closed");
dispatch('close',fws);
}
conn.onopen = function(){
if (debug) console.log("Websocket(" + conn.URL + ") Open");
dispatch('open',fws);
}
conn.onerror = function(e){
if (debug) console.log("Websocket(" + conn.URL + ") Error: " + error);
dispatch('error',fws,e);
}
this.setdebug = function(v) { debug=v; return this; }
var dispatch = function(event_name, message){
var chain = callbacks[event_name];
if(typeof chain == 'undefined') return; // no callbacks for this event
for(var i = 0; i < chain.length; i++){
chain[i]( message )
}
}
};
Then in your browser console:
conn = new FancyWebSocket("ws://yourhostname/ws");