python grpc chat
1.0.0
Application de chat créée avec GRPC. Il s'agissait d'une étude pour le streaming GRPC bidirectionnel.


class ChatServer ( rpc . ChatServerServicer ):
def __init__ ( self ):
# List with all the chat history
self . chats = []
# The stream which will be used to send new messages to clients
def ChatStream ( self , request_iterator , context ):
"""
This is a response-stream type call. This means the server can keep sending messages
Every client opens this connection and waits for server to send new messages
:param request_iterator:
:param context:
:return:
"""
lastindex = 0
# For every client a infinite loop starts (in gRPC's own managed thread)
while True :
# Check if there are any new messages
while len ( self . chats ) > lastindex :
n = self . chats [ lastindex ]
lastindex += 1
yield n
def SendNote ( self , request : chat . Note , context ):
"""
This method is called when a clients sends a Note to the server.
:param request:
:param context:
:return:
"""
print ( "[{}] {}" . format ( request . name , request . message ))
# Add it to the chat history
self . chats . append ( request )
return chat . Empty () address = 'localhost'
port = 11912
class Client :
def __init__ ( self , u : str , window ):
# the frame to put ui components on
self . window = window
self . username = u
# create a gRPC channel + stub
channel = grpc . insecure_channel ( address + ':' + str ( port ))
self . conn = rpc . ChatServerStub ( channel )
# create new listening thread for when new message streams come in
threading . Thread ( target = self . __listen_for_messages , daemon = True ). start ()
self . __setup_ui ()
self . window . mainloop ()
def __listen_for_messages ( self ):
"""
This method will be ran in a separate thread as the main/ui thread, because the for-in call is blocking
when waiting for new messages
"""
for note in self . conn . ChatStream ( chat . Empty ()):
print ( "R[{}] {}" . format ( note . name , note . message ))
self . chat_list . insert ( END , "[{}] {} n " . format ( note . name , note . message ))
def send_message ( self , event ):
"""
This method is called when user enters something into the textbox
"""
message = self . entry_message . get ()
if message is not '' :
n = chat . Note ()
n . name = self . username
n . message = message
print ( "S[{}] {}" . format ( n . name , n . message ))
self . conn . SendNote ( n )
... syntax = "proto3" ;
package grpc ;
message Empty {}
// I called it Note because message Message is annoying to work with
message Note {
string name = 1 ;
string message = 2 ;
}
service ChatServer {
// This bi-directional stream makes it possible to send and receive Notes between 2 persons
rpc ChatStream ( Empty ) returns ( stream Note );
rpc SendNote ( Note ) returns ( Empty );
}