commodity_backingtrack_system/app/blockchain/server/zmq_server.py

158 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import datetime
import random
import zmq
import threading
import json
import os
import time
import blockchain as chain
_basepath = os.path.abspath(os.path.dirname(__file__))
conf = json.load(open(os.path.abspath(os.path.dirname(__file__)) + "\\config.json"))
lock = threading.Lock()
def build_msg(cmd, msg):
data = {
"cmd": cmd,
"msg": msg
}
return data
class ZmqServer(object):
def __init__(self):
self.server = conf["server"]
self.calc_port = conf["calc_port"]
self.add_port = conf["add_port"]
self.signal_port = conf["signal_port"]
self.client_num = conf["client_num"]
self.chain = chain.BlockChain()
print("服务器初始化的链id:%s" % id(self.chain))
self.ops_list = []
self.uncalc_ops = []
self.proof_list = []
def add_ops(self, option):
with lock:
self.ops_list.append(option)
def publish_calc_task(self):
while True:
self.uncalc_ops = list(self.ops_list)
print("未计算的缓存操作列表:%s"%self.uncalc_ops)
print("待计算的操作列表:%s"%self.ops_list)
if len(self.uncalc_ops) > 0:
thread = threading.Thread(target=self.publish_topic,
args=("calc_task", self.uncalc_ops, self.calc_port),
name="calc_task")
thread.start()
time.sleep(15)
def publish_add_task(self, proof):
pub_data = {
"data": list(self.uncalc_ops),
"proof": proof,
"index": len(self.chain.chain) + 1
}
print("即将发布新块:%s" % pub_data)
self.ops_list.clear()
self.chain.new_block(pub_data["data"], pub_data["proof"])
thread = threading.Thread(target=self.publish_topic, args=("add_task", pub_data, self.add_port),
name="add_task")
thread.start()
def check_proofs(self, proof):
with lock:
self.proof_list.append(proof)
temp = list(self.proof_list)
print("收到的证明列表:%s" % temp)
if len(temp) == self.client_num:
max_proof = max(temp, key=temp.count)
print("占大多数的证明:%s" % max_proof)
self.publish_add_task(proof)
self.proof_list.clear()
def publish_topic(self, topic, topic_data, port):
context = zmq.Context()
publisher = context.socket(zmq.PUB)
try:
publisher.bind("tcp://{}:{}".format(self.server, port))
print("publish_topicbind:[%s]:%s" % (self.server, port))
except zmq.ZMQError as e:
print("publish_topicbindfailed:[%s]:%s" % (e, port))
data_string = json.dumps(topic_data, sort_keys=True)
print("publish_topicsend:[%s]:%s" % (topic, data_string))
i = 0
while True:
publisher.send_multipart([bytes(topic, "utf-8"), bytes(data_string, 'utf-8')])
time.sleep(2)
i += 1
if i == 2:
print("publish_topicfinished")
break
publisher.close()
context.term()
def listen_msg(self):
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://{}:{}".format(self.server, self.signal_port))
while True:
message = socket.recv()
message_dict = json.loads(message)
print("Received: %s" % json.dumps(message_dict))
if message_dict["cmd"] == "new_proof":
self.check_proofs(message_dict["msg"])
response_string = json.dumps(build_msg("accept_proof", ""))
socket.send(bytes(response_string, encoding="utf-8"))
elif message_dict["cmd"] == "need_chain":
data_dict = build_msg("new_chain", self.chain.full_chain())
data_string = json.dumps(data_dict)
socket.send(bytes(data_string, encoding="utf-8"))
elif message_dict["cmd"] == "new_ops":
self.add_ops(message_dict["msg"])
response_string = json.dumps(build_msg("accept_ops", ""))
socket.send(bytes(response_string, encoding="utf-8"))
def add_fake_data(self):
while True:
data = (
{
"id": random.randint(0, 9),
"operator": "operator",
"option": "option",
"commodity": "commodity",
"time": get_current_time()
}
)
self.add_ops(data)
time.sleep(9)
def get_current_time(frm="%Y-%m-%d %H:%M:%S"):
dt = datetime.datetime.now()
return dt.strftime(frm)
if __name__ == '__main__':
server = ZmqServer()
# add_fake_thread = threading.Thread(target=server.add_fake_data, name="客户端消息监听")
# add_fake_thread.start()
publish_calc_task_thread = threading.Thread(target=server.publish_calc_task, name="客户端消息监听")
publish_calc_task_thread.start()
listen_thread = threading.Thread(target=server.listen_msg, name="客户端消息监听")
listen_thread.start()