Python Development Program: RPC asynchronous command execution (RabbitMQ bidirectional communication), pythonrabbitmq

Source: Internet
Author: User

Python Development Program: RPC asynchronous command execution (RabbitMQ bidirectional communication), pythonrabbitmq

RPC asynchronous Command Execution
Requirements:
  • Use RibbitMQ for Data Interaction
  • Allows you to operate on multiple servers.
  • After the command is executed, you do not need to wait for the command execution result. Instead, you can directly input the next command and print the result automatically.
  • Implement Asynchronous operations

Do not understand rpc please move to the http://www.cnblogs.com/lianzhilei/p/5977545.html (bottom)

This section involves the most about rabbitmq Communication Principles and requires the installation of the rabbitmq service.

 

 

Program directory structure:

Program introduction:

# Asynchronous rpc program # blog Address [11th days blog address] (http://www.cnblogs.com/lianzhilei/p/5970176.html) (http://www.cnblogs.com/lianzhilei/p/5970176.html) #1. requirement-[] Use RibbitMQ for Data Interaction-[] operations on multiple servers-[] do not wait for the command execution result after the command is executed, instead, you can directly input the next command and print the result automatically-[] implement asynchronous operations # Note-[] RabbitMQ queue name: ① when executing the command, the queue name is the IP address of the server. ② When querying data, the callback_queue name randomly generated during callback-[] threading multithreading is used: the command is executed without waiting for the execution result, you can still enter the new command-[] execution command format: --> run "dir" host 192.168.20.22 192.168.20.23 the command host to be executed by the dir server can be followed by one or more server addresses of rabbitMQ-[] to view all backend task_ids information: --> check_all: TASK_ID [76786] HOST [192.168.20.22] COMMAND [dir] TASK_ID [10307] HOST [192.168.20.23] COMMAND [dir]-[] view the execution result of TASK_ID: --> check_task 10307 10307 is the TASK_ID found by check_all.
README. md

Program flowchart:

Server:

#! /Usr/bin/env python #-*-coding: UTF-8-*-#-Author-Lian #! /Usr/bin/env python #-*-coding: UTF-8-*-#-Author-Lianimport pikaimport osclass Server (object): def _ init _ (self, rabbitmq, queue_name): self. queue_name = queue_name self. connection = pika. blockingConnection (pika. connectionParameters (host = rabbitmq) self. channel = self. connection. channel () self. channel. queue_declare (queue = self. queue_name) def handle (self, command): command = command. decode () print (command, type (command) message = OS. popen (command ). read () if not message: message = "Wrong Command" return message def on_request (self, ch, method, props, body): response = self. handle (body) ch. basic_publish (exchange = '', routing_key = props. reply_to, # return information queue name properties = pika. basicProperties (correlation_id = props. correlation_id), body = str (response) ch. basic_ack (delivery_tag = method. delivery_tag) def start (self): self. channel. basic_consume (self. on_request, queue = self. queue_name) print ("[x] Awaiting RPC requests") self. channel. start_consuming () if _ name _ = "_ main __": rabbitmq = "localhost" # rabbitmq server address queue_name = "192.168.20.22" # queue_name is the local IP address Server = server (rabbitmq, queue_name) server. start ()
Server. py

 

Client:

Bin directory:

#! /Usr/bin/env python #-*-coding: UTF-8-*-import sysimport osimport platform # Add BASE_DIR and add the top-level directory to the path to facilitate calling other directory modules if platform. system () = 'windows': print (OS. path. abspath (OS. path. dirname (_ file __)). split ('\') [:-1]) BASE_DIR = '\\'. join (OS. path. abspath (OS. path. dirname (_ file __)). split ('\') [:-1]) else: BASE_DIR = '/'. join (OS. path. abspath (OS. path. dirname (_ file __)). split ('/') [:-1]) # load the environment variable sys. path. append (BASE_DIR) from conf import settingsfrom core import mainif _ name _ = '_ main _': obj = main. handler () obj. start ()
Start. py

Conf directory:

#! /Usr/bin/env python #-*-coding: UTF-8-*-_ author _ = 'luotianshuai' import osimport sysimport platformif platform. system () = 'windows': BASE_DIR = '\\'. join (OS. path. abspath (OS. path. dirname (_ file __)). split ('\') [:-1]) school_dbpaths = OS. path. join (BASE_DIR, 'school _ db') else: BASE_DIR = '/'. join (OS. path. abspath (OS. path. dirname (_ file __)). split ('/') [:-1]) school_dbpaths = OS. path. join (BASE_DIR, 'school _ db') # rabbitmq service address ipRabbitMQ_IP = 'localhost'
Settings. py

Core directory

#! /Usr/bin/env python #-*-coding: UTF-8-*-#-Author-Lianfrom conf import settingsfrom modules. client import Clientimport random, timeimport threadingclass Handler (object): def _ init _ (self): self. information ={}# background process information def check_all (self, * args): ''' view all task_id information ''' time. sleep (2) for key in self. information: print ("TASK_ID [% s] \ tHOST [% s] \ tCOMMAND [% s]" % (key, self. information [key] [0], self. information [key] [1]) def check_task (self, user_cmd): ''' view task_id execution result ''' time. sleep (2) try: task_id = user_assist.split () [1] task_id = int (task_id) callback_queue = self. information [task_id] [2] callback_id = self. information [task_id] [3] client = Client () response = client. get_response (callback_queue, callback_id) print (response. decode () del self. information [task_id] doesn t KeyError as e: print ("\ 33 [31; 0 mWrong id [% s] \ 33 [0 m" % e) Doesn't IndexError as e: print ("\ 33 [31; 0 mWrong id [% s] \ 33 [0 m" % e) def run (self, user_cmd ): '''execute the command ''' try: time. sleep (2) # print ("--->", user_cmd) command = user_assist.split ("\" ") [1] hosts = user_assist.split () [3:] for host in hosts: task_id = random. randint (10000,999 99) client = Client () response = client. call (host, command) # print (response) self. information [task_id] = [host, command, response [0], response [1] handle T IndexError as e: print ("\ 33 [31; 0 mError: % s \ 33 [0 m "% e) def reflect (self, str, user_cmd): '''reflection ''' if hasattr (self, str): getattr (self, str) (user_cmd) # else: # setattr (self, str, self. foo) # getattr (self, str) () def start (self): while True: user_cmd = input ("-> "). strip () if not user_cmd: continue str = user_assist.split () [0] t1 = threading. thread (target = self. reflect, args = (str, user_cmd) # multithreading t1.start ()
Main. py

Modules directory

#! /Usr/bin/env python #-*-coding: UTF-8-*-#-Author-Lianimport pikaimport uuidfrom conf import settingsclass Client (object ): def _ init _ (self): self. connection = pika. blockingConnection (pika. connectionParameters (host = settings. rabbitMQ_IP) self. channel = self. connection. channel () def on_response (self, ch, method, props, body): ''' callback function for obtaining command execution results ''' # print ("Verification code check", self. callback_id, props. correlation_id) if self. callback_id = props. correlation_id: # verify self with the verification code. response = body ch. basic_ack (delivery_tag = method. delivery_tag) def get_response (self, callback_queue, callback_id): ''' get the value in the queue and obtain the callback_queued execution result ''' self. callback_id = callback_id self. response = None self. channel. basic_consume (self. on_response, # Run on_response queue = callback_queue) while self. response is None: self. connection. process_data_events () # start_consuming return self. response def call (self, queue_name, command): ''' data sent in the queue ''' result = self. channel. queue_declare (exclusive = False) # exclusive = False must be written in this way. callback_queue = result. method. queue self. required _id = str (uuid. uuid4 () # print (self. consumed _id) self. channel. basic_publish (exchange = '', routing_key = queue_name, properties = pika. basicProperties (reply_to = self. callback_queue, # name correlation_id = self. required _id, # Send the uuid equivalent to the Verification Code), body = command) return self. callback_queue, self. consumer _id
Client. py

 

 

Running example

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.