pyzmq poller for both recv and send messages - zeromq

pyzmq poller does not work if i register it with both POLLIN and POLLOUT.
The if condition could not catch the POLLIN event
server.py
import zmq
import random
import sys
import time
port = "5556"
context = zmq.Context()
socket = context.socket(zmq.DEALER)
socket.bind("tcp://*:5556")
while True:
socket.send(b"Server")
client.py
import zmq
import random
import sys
import time
port = "5556"
context = zmq.Context()
socket = context.socket(zmq.DEALER)
socket.connect("tcp://localhost:5556")
poller = zmq.Poller()
poller.register(socket, zmq.POLLIN|zmq.POLLOUT)
while True:
socks = dict(poller.poll(50))
if socket in socks and socks[socket] == zmq.POLLIN:
msg = socket.recv()
print(msg)

The integer values for zmq.POLLIN, zmq.POLLOUT and zmq.POLLIN | zmq.POLLOUT are 1, 2 and 3 respectively:
>>> zmq.POLLIN, zmq.POLLOUT, zmq.POLLIN | zmq.POLLOUT
(1, 2, 3)
So if in your client side the if statement is expecting receive in the socket it must await for a zmq.POLLIN (1) state, but also a zmq.POLLIN | zmq.POLLOUT (3) state, since they are exclusive.
Rewriting your if statement:
if socket in socks and socks[socket] in (zmq.POLLIN, zmq.POLLIN | zmq.POLLOUT):
# your code
...
Same way, if you want to send in the socket must await for zmq.POLLOUT (2) and zmq.POLLIN | zmq.POLLOUT (3) states.

Related

How to add new thread for every new client in python websockets?

import asyncio
import websockets
import threading
async def server_handle(websocket,path):
print("Server is waiting!!!!")
while True:
msg = await websocket.recv()
print(f"Client : {msg}")
await websocket.send(input("Server : "))
def add_new_clients():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
start_server = websockets.serve(server_handle, "localhost", 1234)
loop.run_until_complete(start_server)
loop.run_forever()
loop.close()
total_clients = 0
if __name__ == "__main__":
# daemon server thread:
server = threading.Thread(target=add_new_clients, daemon=True)
server.start()
total_clients+=1
print(f"total clients : {total_clients}")
Here i am trying to add new thread to handle each clients request seperately using python websockets . for example if client1 connects to the server one thread should be created and sholud take care of the request and responce of that particular client. is there any way?.

Having two scripts publishing on the same port with zmq

I would like to have two python scripts (it can be more in real use) that publishes on the same port to a single client. Here is the code for my scripts:
server1.py:
import time
import zmq
ctx = zmq.Context()
s1 = ctx.socket(zmq.PUB)
s1.connect("tcp://127.0.0.1:5566")
for i in range(10):
s1.send_pyobj({'job':'publisher 1','yo':10})
time.sleep(5)
server2.py:
import time
import zmq
ctx = zmq.Context()
s2 = ctx.socket(zmq.PUB)
s2.connect("tcp://127.0.0.1:5566")
for i in range(10):
s2.send_pyobj({'job':'publisher 2','yo':10})
time.sleep(5)
client.py:
import zmq
ctx = zmq.Context()
c = ctx.socket(zmq.SUB)
c.bind("tcp://127.0.0.1:5566")
c.setsockopt(zmq.SUBSCRIBE, '')
while True:
msg = c.recv_pyobj()
print("MSG: ", msg)
This naive implementation works but, being new to zmq,I was wondering if it was indeed the right implementation or if there was a better way to proceed.
I think that your design is valid. However, as the comments to the answer in this similar question suggest, you might struggle to subscribe with multiple clients with this architecture.

Websocket with Locust, no error but no data

The fixed code (from https://medium.com/#rajatsaxena120/websockets-in-python-d91c7bc2fd22, https://stackoverflow.com/questions/ask?newreg=520c9b343e534667aa88f67ea3f79cb4) seems to work:
import time, websocket
from locust import HttpUser, task, between, events
from websocket import create_connection
import gevent
class QuickstartUser(HttpUser):
wait_time = between(1, 5)
#task
def on_start(self):
ws = create_connection('wss://REDACTED.com')
g = gevent.spawn(self.connect)
g.get(block=True, timeout=10)
g = gevent.spawn(self.subscribe)
g.get(block=True, timeout=10)
g = gevent.spawn(self.send)
g.get(block=True, timeout=10)
def _receive():
ws = create_connection('wss://REDACTED.com')
while True:
res = ws.recv()
events.request_success.fire(
request_type='Websocket Receive Message',
name='test websocket message receive',
response_time=0,
response_length=len(res)
)
gevent.spawn(_receive)
But when running tests, nothing happen, no connection to websocket, no load on the server.
What am I missing?

WinError 10038 an operaton was attempted on something that is not a socket

I'm trying to make chatting server in Python and I can't solve it. I'm running my code in CMD by using command python client.py localhost 9009.
this is the code that I am using:
#chat_client.py
import sys
import socket
import select
def chat_client():
if(len(sys.argv) < 3):
print("Usage: python chat_client.py hostname port")
sys.exit()
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
# connect to remote host
try:
s.connect((host, port))
except:
print("Unable to connect")
sys.exit()
print("Connected to remote host. You can start sending messages")
sys.stdout.write("[Me] "); sys.stdout.flush()
while 1:
socket_list = [sys.stdin, s]
# Get the list sockets which are readable
read_sockets, write_sockets, error_sockets = select.select(socket_list , [], [])
for sock in read_sockets:
if sock == s:
# incoming message from remote server, s
data = sock.recv(4096)
if not data:
print("\nDisconnected from chat server")
sys.exit()
else:
#print data
sys.stdout.write(data)
sys.stdout.write("[Me] "); sys.stdout.flush()
else:
# user entered a message
msg = sys.stdin.readline()
s.send(msg)
sys.stdout.write("[Me] "); sys.stdout.flush()
if __name__ == "__main__":
sys.exit(chat_client())
And this is the error that I'm getting:
I don't have a clue how to fix it. Help would be appreciated! :)
[Me] Traceback (most recent call last):
File "client.py", line 54, in <module>
sys.exit(chat_client())
File "client.py", line 32, in chat_client
read_sockets, write_sockets, error_sockets = select.select(socket_list , [],
[])

In haskell,socket listening failed on windows

I asked a question about signal on windows with the same code,here is another question
import IO
import Control.Exception hiding (catch)
import Control.Concurrent
import Network
main = withSocketsDo $ do {main'}
main' = listenOn (PortNumber 9900) >>= acceptConnections
acceptConnections sock = do
putStrLn $ "trying to accept" ++ (show sock)-- debug msg
conn#(h,host,port) <- accept sock
print conn -- debug msg
forkIO $ catch (talk conn `finally` hClose h) (\e -> print e)
acceptConnections sock
talk conn#(h,_,_) = hGetLine h >>= hPutStrLn h >> hFlush h >> talk conn
I run the program on win7,and it looks like the socket created succeed,but I can't telnet on,and netstat doesn't show any listening socket with the process,is there anything wrong?Or,haskell has bug on windows?(By the way,on debian with this code works perfect)
when I use netstat -a on win7,I found the listening ip with port 9900 is [::],neither is 127.0.0.1 nor 0.0.0.0,so I guess the problem is during create socket in function "listenOn",then I wrote "listenOn2" replaced.And the problem is solved.
Here is the full code:(the only difference is change the proto from [[getProtocolNumber "tcp"]] to [[defaultProtocol]]),maybe this is a bug.
import IO
import Control.Exception hiding (catch)
import Control.Concurrent
import Network
import Network.Socket
listenOn2 (PortNumber port) = do
--proto <- getProtocolNumber "tcp" ,here is the difference!!!!
let proto = defaultProtocol
bracketOnError
(socket AF_INET Stream proto)
(sClose)
(\sock -> do
setSocketOption sock ReuseAddr 1
--addr <- inet_addr "127.0.0.1"
bindSocket sock (SockAddrInet port iNADDR_ANY)
listen sock maxListenQueue
return sock
)
main = withSocketsDo $ do {main'}
main' = listenOn2 (PortNumber 9900) >>= acceptConnections
acceptConnections sock = do
putStrLn $ "trying to accept" ++ (show sock)-- debug msg
conn#(h,host,port) <- Network.accept sock
print conn -- debug msg
forkIO $ catch (talk conn `finally` hClose h) (\e -> print e)
acceptConnections sock
talk conn#(h,_,_) = hGetLine h >>= hPutStrLn h >> hFlush h >> talk conn

Resources