0% acharam este documento útil (0 voto)
10 visualizações12 páginas

Implementação de RPC em Python

Este relatório descreve um trabalho prático sobre chamadas de procedimento remoto (RPC) usando a biblioteca XML-RPC do Python. Dois programas foram implementados para trocar mensagens através de RPC, evitando o uso de sockets diretamente. Uma interface gráfica foi criada para exibir as mensagens recebidas e enviar novas.

Enviado por

Tássis Fernando
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
10 visualizações12 páginas

Implementação de RPC em Python

Este relatório descreve um trabalho prático sobre chamadas de procedimento remoto (RPC) usando a biblioteca XML-RPC do Python. Dois programas foram implementados para trocar mensagens através de RPC, evitando o uso de sockets diretamente. Uma interface gráfica foi criada para exibir as mensagens recebidas e enviar novas.

Enviado por

Tássis Fernando
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

CENTRO FEDERAL DE EDUCAÇÃO TECNOLÓGICA DE MINAS GERAIS

CAMPUS VII - UNIDADE TIMÓTEO - Engenharia de Computação


Sistemas Distribuídos
Lucas Pantuza Amorim

Trabalho Prático 2:
RPC/RMI

Diêgo Gomes Piovezana, Habacuque Boy Barbosa Neves

1 Introdução

Neste relatório estão descritos os procedimentos realizados para execução do 2º trabalho prático da
disciplina de Sistemas Distribuídos do curso de Engenharia de Computação do CEFET-MG, campus Ti-
móteo. Tal feito utiliza como base o trabalho anterior, ou seja, foi implementado um par de programas
operando no modelo ponto-a-ponto e utilizado chamadas remotas de procedimento utilizando a lin-
guagem de programação Python. Porém, em especial a esta atividade, em divergência com o trabalho
base, não foi feito uso de soquete como método de comunicação, mas sim, utilizado a tecnologia de
Chamada de Procedimento Remoto (RPC) [1], mais precisamente foi utilizado a biblioteca nativa da
linguagem, intitulada ’xmlrpc’.

2 Metodologia

Utilizando o ambiente Linux com Python 3.9.1 devidamente instalado e configurado e novamente fa-
zendo uso da biblioteca ’tkinter’ instalada utilizando o comando ’pip’, foi criado um módulo chamado
’[Link]’ que utiliza a biblioteca nativa ’xmlrpc’ do Python. Para tal feito, foi utilizado a documenta-
ção oficial [2].

O módulo exporta uma função para ’escutar’ mensagens que cria em um servidor (server) que imple-
menta o protocolo ’xmlrpc’ no processo, na qual expõe remotamente uma função ’onMessage’ passada
como argumento. Também é exportada uma função que retorna outra função para enviar mensagens
para um server remoto, criando um cliente ’xmlrpc’ que se comunica chamando a função ’onMessage’
do server remoto. Uma característica especial da função de escutar mensagens RPC é que ela executa
um server em ’looping’. Logo, foi transferida para outra thread, para não bloquear o programa.
Sistemas Distribuídos
Lucas Pantuza Amorim

Por fim, também foi criado um módulo para desenhar as telas do programa utilizando a biblioteca ’tkin-
ter’ (Código 2). Este módulo desenha uma tela de login onde é possível inserir o endereço do server RPC
remoto e uma tela de chat onde ocorre a comunicação de fato. As telas chamam as funções relevantes
do módulo de RPC citado anteriormente.

Ao criar a tela de chat o programa assume que o server remoto (IP passado na tela de login) está escu-
tando na porta 8000. Em seguida tenta enviar uma mensagem com o conteúdo ’ack’ (veja a figura 6).
Caso o envio falhe o programa iniciará um server ’xmlrpc’ na porta 8000 e assumirá que o outro está na
porta 8001. Caso o envio seja bem sucedido o programa criará um server na porta 8001 e continuará
assumindo que o server remoto está na porta 8000.

3 Resultados

As mensagens conseguiram ser trocadas normalmente entre dois softwares. Contudo, ao abrir uma
quantidade superior de programas, um erro (provido do server ao tentar escutar mensagens numa porta
ocupada) informando que o endereço já está sendo utilizado será imprimido no console para cada
novo programa aberto (veja a figura 8). Todavia, eles continuarão abertos sendo até capazes de enviar
mensagens (para o server na porta 8000), mas não são capazes de receber.

3.1 Comando para iniciar o sistema

Figura 1: Comando para iniciar o sistema


Sistemas Distribuídos
Lucas Pantuza Amorim

3.2 Tela de login

Figura 2: Tela de login do sistema

3.3 Tela do chat

Figura 3: Tela do chat


Sistemas Distribuídos
Lucas Pantuza Amorim

3.4 Comunicação cliente/servidor

Figura 4: Chat cliente/servidor

3.5 Mensagem ’ack’

Figura 5: Primeira mensagem ’ack’ enviada ao destinatário


Sistemas Distribuídos
Lucas Pantuza Amorim

3.6 Comportamento sem e com destinatário

Figura 6: Comportamento quando um destinatário (outro/cliente 2) entra no chat

3.7 Erros

3.7.1 Ausência de destinatário

Figura 7: Erro para quando não há ninguém para receber uma mensagem
Sistemas Distribuídos
Lucas Pantuza Amorim

3.7.2 Endereço em uso

Figura 8: Erro quando o endereço já está sendo utilizado

4 Análise

O programa em RPC foi muito mais resiliente e fácil de implementar se comparado ao software utili-
zando soquetes. Tal comportamento talvez se deve ao fato de utilizar uma abstração de mais alto nível
com mais uma camada de robustez adicionada pelo protocolo ’xmlrpc’ ao invés de TCP puro.

5 Conclusão

Com a realização deste trabalho prático, instigou-se uma compreensão prática do conceitos teóricos
abordados na disciplina de Sistemas Distribuídos, de modo especial, ao que se refere à comunicação
entre processos, fazendo uso de chamadas de procedimento remoto (RPC), sendo portanto outro me-
canismo (com algumas vantagens) para realizar a comunicação entre processos, além da alternativa
abordada no trabalho anterior da disciplina, na qual foi base para realizada deste.

6 Código Fonte da Aplicação


Sistemas Distribuídos
Lucas Pantuza Amorim

6.1 Main
1 import g u i U t i l s
2
3 d e f main ( ) :
4 # desenha a t e l a
5 gui = guiUtils . create ()
6
7 main ( )

codigo/[Link]

6.2 Interface Gráfica


1 # b i b l i o t e c a de i n t e r f a c e g r a f i c a p a r a p y t h o n
2 import t k i n t e r as tk
3 import t k i n t e r . s c r o l l e d t e x t
4
5 # b i b l i o t e c a n a t i v a de t h r e a d s do p y t h o n
6 import threading
7
8 # n o s s a b i b l i o t e c a de r p c
9 import r p c U t i l s
10
11 # c r i a uma j a n e l a de f u n d o c o l o r i d o em t e l a c h e i a
12 d e f window ( ) :
13 window = t k . Tk ( )
14 w i n d o w . o p t i o n _ a d d ( ’ * F o n t ’ , ’ 30 ’ )
15 w i n d o w . a t t r i b u t e s ( ’ − zoomed ’ , T r u e )
16 window . c o n f i g u r e ( b a c k g r o u n d = ’# e 5 f 2 f c ’ )
17 window . t i t l e ( " c h a t " )
18 r e t u r n window
19
20
21 # c r i a a t e l a de c h a t s
22 def chatScreen ( host ) :
23

24 # a s s u m i m o s que e x i s t e um s e r v e r r p c e s c u t a n d o n a p o r t a 8000
25 send = r p c U t i l s . s e n d C r e a t e ( host ,8000)
26 # a s s u m i m o s que s e r v e r s a b e que n o s s o s e r v e r l o c a l e s t a na p o r t a 8001
27 s e l f P o r t = 8001
28
29 # t e n t a m a n d a r uma mensagem g e n e r i c a
30 try :
31 send ( ’ ack ’ )
Sistemas Distribuídos
Lucas Pantuza Amorim

32 except :
33 # e n v i o da mensagem f a l h o u
34 # l o g o o s e r v e r n a o e s t a v a n a p o r t a 8000
35 # a s s u m i m o s que e l e e s t a n a 8001
36 send = r p c U t i l s . sendCreate ( host ,8001)
37 # e que o s e r v e r r e m o t o v a i a s s u m i r que e s t a m o s na 8000
38 s e l f P o r t = 8000
39

40
41 # v a r i a v e l que g u a r d a mensagem s e n d o e s c r i t a
42 msg = t k . S t r i n g V a r ( )
43
44 # e q u i v a l e n t e a um ’ d i v ’ no h t m l
45 f r a m e = t k . F r a m e ( bg = " w h i t e " )
46 e n t r y F r a m e = t k . F r a m e ( f r a m e , bg = " w h i t e " )
47
48 # um t e x t o q u a l q u e r
49 t i t l e = t k . L a b e l ( f r a m e , t e x t = " C h a t " , f g = " b l a c k " , bg = " w h i t e " , f o n t = ( " a r i a l "
,25) )
50

51 # uma a r e a de t e x t o com r o l a g e m n a o e d i t a v e l
52 # para mostrarmos mensagens r e c e b i d a s
53 t e x t = t k . s c r o l l e d t e x t . S c r o l l e d T e x t ( f r a m e , w r a p = t k . WORD , f g = " b l a c k " , bg = "
white " )
54 t e x t . v b a r . c o n f i g ( bg = " w h i t e " )
55 t e x t . c o n f i g ( s t a t e = t k . DISABLED )
56
57 # um i n p u t de t e x t o
58 e n t r y = t k . E n t r y ( e n t r y F r a m e , f g = " b l a c k " , bg = " w h i t e " , w i d t h = 5 0 ,
t e x t v a r i a b l e = msg )
59
60 # d e i x a a c a i x a de t e x t o e d i t a v e l
61 # a d i c i o n a uma mensagem n e l a
62 # d e s a t i v a a e d i c a o l o g o em s e g u i t a
63 # t y p e i n d i c a i n f o r m a c o e s s o b r e quem mandou a mensagem
64 d e f a p p e n d M s g ( msg , t y p e ) :
65 t e x t . c o n f i g ( s t a t e = t k . NORMAL )
66 t e x t . i n s e r t ( t k . INSERT , t y p e + " : " + msg + " \ n " )
67 t e x t . c o n f i g ( s t a t e = t k . DISABLED )
68
69 # c r i a um s e r v e r r p c p a r a que p e r m i t i r a c h a m a r a f u n c a o ’ a p p e n d M s g ’
remotamente
70 # com uma mensagem de a r g u m e n t o
71 def l i s t e n M s g ( ) :
72 r p c U t i l s . l i s t e n ( s e l f P o r t , l a m b d a msg : a p p e n d M s g ( msg , " o u t r o "
) )
73
74 # chama uma f u n c a o r e m o t a com uma mensagem que e s c r e v e m o s
Sistemas Distribuídos
Lucas Pantuza Amorim

75 def sendMsg ( ) :
76 # i g n o r a m e n s a g e n s v a z i a s ou m a i o r e s que 1 0 2 4 b y t e s
77 i f ( msg . g e t ( ) a n d l e n ( msg . g e t ( ) ) < = 1 0 2 4 ) :
78 try :
79 # chama a r p c de r e c e b e r m e n s a g e n s
80 # mandando p a r a o s e r v e r a mensagem que e s t a v a m o s
escrevendo
81 s e n d ( msg . g e t ( ) )
82 # s a l v a n o s s a p r o p i a mensagem n a l i s t a v i s i v e l de
mensagens
83 a p p e n d M s g ( msg . g e t ( ) , " eu " )
84 except :
85 # e n v i o da mensagem f a l h o u
86 # i n d i q u e na t e l a a f a l h a
87 appendMsg ( ’ n o h n i n g u m p a r a r e c e b e r s u a mensagem ’ ,
" erro " )
88 # l i m p a o campo de e s c r i t a de mensagem
89 msg . s e t ( ’ ’ )
90
91

92 # b o t a o de e n v i o de mensagem
93 b u t t o n = t k . B u t t o n ( e n t r y F r a m e , t e x t = " E n v i a r " , f g = " b l a c k " , bg = " w h i t e " ,
command = s e n d M s g )
94
95 # p o s i c i o n a e l e m e n t o s na t e l a
96

97 e n t r y . g r i d ( column =0 , row =0 , padx = 1 0 )


98 b u t t o n . g r i d ( column = 1 , row =0 , padx = 1 0 , pady = 1 0 )
99
100 t i t l e . pack ( padx = 1 0 )
101 t e x t . pack ( expand = 1 , f i l l = tk . Y )
102 entryFrame . pack ( )
103
104 frame . pack ( expand = 1 , f i l l = tk . Y )
105
106 # como o s e r v e r r p c eh um l o o p i n f i n i t o
107 # ele t r a v a r i a o programa
108 # logo jogamos ele para outra thread
109 thread = t h r e a d i n g . Thread ( t a r g e t = l i s t e n M s g )
110 thread . s t a r t ( )
111
112
113 # g e r a uma t e l a de l o g i n
114 # o n d e i n f o r m a m o s o i p de quem v a i r e c e b e r n o s s a s m e n s a g e n s
115 def l o g i n S c r e e n ( ) :
116
117 # div
118 f r a m e = t k . F r a m e ( bg = " w h i t e " )
Sistemas Distribuídos
Lucas Pantuza Amorim

119 # input
120 e n t r y F r a m e = t k . F r a m e ( f r a m e , bg = " w h i t e " )
121

122 # v a r i a v e l que g u a r d a o i p
123 remoteHost = tk . S t r i n g V a r ( )
124 remoteHost . set ( ’ 1 2 7 . 0 . 0 . 1 ’ )
125
126 # texto qualquer
127 t i t l e = t k . L a b e l ( f r a m e , t e x t = " I n s i r a o e n d e r e o da o u t r a p e s s o a " , f g = "
b l a c k " , bg = " w h i t e " , f o n t = ( " a r i a l " , 2 5 ) )
128
129 # i n p u t o n d e o i p eh i n s e r i d o
130 e n t r y = tk . E n t r y ( entryFrame , t e x t v a r i a b l e = remoteHost , j u s t i f y = " c e n t e r " ,
f g = " b l a c k " , bg = " w h i t e " )
131
132 # d e s t r o i a t e l a a t u a l e v a i p a r a a t e l a de c h a t s
133 # passando o host i n s e r i d o
134 def goToChatScreen ( ) :
135 frame . d e s t r o y ( )
136 chatScreen ( remoteHost . get ( ) )
137
138 # b o t a o de mudar de t e l a
139 b u t t o n = t k . B u t t o n ( f r a m e , t e x t = " E n v i a r " , f g = " b l a c k " , bg = " w h i t e " , command =
goToChatScreen )
140
141 # c o l o c a os e l e m e n t o s na t e l a
142
143 t i t l e . pack ( pady =30 , padx = 1 0 )
144
145 entryFrame . pack ( )
146 e n t r y . g r i d ( column =0 , row =0 , padx = 1 0 )
147

148 b u t t o n . pack ( pady =20)


149
150 frame . pl ace ( r e l x =0.5 , r e l y =0.5 , anchor = ’ c e n t e r ’ )
151
152 r e t u r n frame
153

154
155
156
157 def crea te ( ) :
158
159 w = window ( )
160
161 # q u a n d o o c o r r e r um e r r o
162 # d e s t r u a o j a n e l a e m o s t r e e l e no c o n s o l e
163 def s h o w E r r o r ( s e l f , exc , val , tb ) :
Sistemas Distribuídos
Lucas Pantuza Amorim

164 w. destroy ()
165 print ( val )
166 t k . Tk . r e p o r t _ c a l l b a c k _ e x c e p t i o n = s h o w E r r o r
167
168 # cria tela delogin
169 ls = loginScreen ()
170
171 # desenha t e l a para sempre
172 w . mainloop ( )

codigo/[Link]

6.3 RPC
1 # b i b l i o t e c a n a t i v a do p y t h o n p a r a r p c
2 import xmlrpc . server
3 import xmlrpc . c l i e n t
4
5 # c r i a um s e r v e r do p r o t o c o l o x m l r p c
6 # com uma f u n c a o p a r a r e c e b e r m e n s a g e n s
7 def l i s t e n ( s e l f P o r t , onMessage ) :
8 # c r i a o s e r v e r e p e e p a r a e l e e s c u t a r numa d e t e r m i n a d a p o r t a
9 # o a l l o w _ n o n e , p e r m i t e n o s s a s f u n c o e s r p c nao r e t o r n a r e m v a l o r e s
10 s e r v e r = xmlrpc . s e r v e r . SimpleXMLRPCServer ( ( ’ l o c a l h o s t ’ , s e l f P o r t ) ,
allow_none = True )
11 # r e g i s t r a uma f u n c a o c h a m a d a ’ o n M e s s a g e ’ que eh a mesma que ’
o n M e s s a g e ’ r e c e b i d a como a r g u m e n t o
12 s e r v e r . r e g i s t e r _ f u n c t i o n ( onMessage , ’ onMessage ’ )
13 # c o l o c a o s e r v e r p a r a e x e c u t a r em l o o p
14 server . serve_forever ()
15
16 # c r i a um c l i e n t e do p r o t o c o l o x m l r p c
17 # e c r i a uma f u n c a o que u s a o c l i e n t e p a r a c h a m a r a f u n c a o r e m o t a ’
onMessage ’
18 # do s e r v e r que c o n e c t a m o s
19 def sendCreate ( remoteHost , remotePort ) :
20 # cria o cliente
21 remoteServer = xmlrpc . c l i e n t . ServerProxy ( f " http : / / { remoteHost } : {
remotePort } " , allow_none = True )
22 # chama a f u n c a o r e m o t a ’ o n M e s s a g e ’ , eh o e q u i v a l e n t e de e n v i a r m o s
uma mensagem p a r a o s e r v i d o r
23 r e t u r n remoteServer . onMessage

codigo/[Link]
Sistemas Distribuídos
Lucas Pantuza Amorim

Referências
[1] DEINFO. RPC - O que é. URL [Link] alunoso/2017/RPC/.

[2] Python Software Foundation. [Link] — Basic XML-RPC servers, 2021. URL
[Link]

Você também pode gostar