Last Updated on 2021-04-13 by Clay
我之前寫了一個簡單的 Socket 教學,如果還不熟悉使用 Python 中的 Socket 的話請看這裡:[Python] socket 模組基本教學
就如同這篇簡單的教學所提的,我希望能夠透過 Socket 建立一個簡單的,只會重複你說話的 ChatBot,就跟大部分的 LineBot 教學一樣。(畢竟,要設定怎麼回覆使用者的話,就要看大家需要什麼『聊天主題』、要怎麼設計『檢索系統』了。)
那麼,廢話不多說,貼上範例程式吧!
同樣地,若想參閱 Python 官方的 Socket 教學,也許你可以參考這個:https://docs.python.org/3/howto/sockets.html
Server.py
# -*- coding: utf-8 -*- import json import socket # HOST & PORT with open('HOST_PORT.json', 'r', encoding='utf-8') as f: HOST_PORT = json.load(f) HOST = HOST_PORT['HOST'] PORT = int(HOST_PORT['PORT']) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((HOST, PORT)) server.listen(5) while True: conn, addr = server.accept() clientMessage = str(conn.recv(1024), encoding='utf-8') print('Client message is:', clientMessage) # Repeat serverMessage = clientMessage conn.sendall(serverMessage.encode()) conn.close()
Server 端我是設在主機上,為了避免透漏 IP 地址,還麻煩無視我使用 Json 檔讀入的動作。
如果要使用,只需要在 HOST 欄位填上 string 型態的你的主機 IP 即可。 PORT 可以隨意設定,只要不要填入已經正在啟用的,並且在 Client 端也保持一樣的 PORT 即可。
執行程式,然後開始著手於 Client 端吧。
界面
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'socket_chatbot.ui' # # Created by: PyQt5 UI code generator 5.11.3 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(981, 749) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget) self.textBrowser.setGeometry(QtCore.QRect(0, 0, 981, 591)) font = QtGui.QFont() font.setFamily("Arial") font.setPointSize(12) font.setBold(True) font.setWeight(75) self.textBrowser.setFont(font) self.textBrowser.setObjectName("textBrowser") self.textEdit = QtWidgets.QTextEdit(self.centralwidget) self.textEdit.setGeometry(QtCore.QRect(3, 600, 701, 87)) font = QtGui.QFont() font.setFamily("Arial") font.setPointSize(12) font.setBold(True) font.setWeight(75) self.textEdit.setFont(font) self.textEdit.setObjectName("textEdit") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(720, 595, 231, 101)) font = QtGui.QFont() font.setFamily("Arial") font.setPointSize(28) font.setBold(True) font.setWeight(75) self.pushButton.setFont(font) self.pushButton.setStyleSheet("color: rgb(255, 255, 255);\n" "background-color: rgb(220, 0, 0);\n"
這是我使用 Qt Designer 製作的界面,若是對製作界面有興趣,可以參考我的心得筆記: PyQt5 基本教學
Client.py
# -*- coding: utf-8 -*- import sys import json import socket from PyQt5 import QtWidgets from socket_chatbot import Ui_MainWindow # HOST & PORT with open('HOST_PORT.json', 'r', encoding='utf-8') as f: HOST_PORT = json.load(f) class MainWindow(QtWidgets.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.textBrowser.append('<font color="#FF0000">Server: Hello! I will repeat what you said!</font>') self.HOST = HOST_PORT['HOST'] self.PORT = int(HOST_PORT['PORT']) self.ui.pushButton.clicked.connect(self.buttonEvent) def buttonEvent(self): text = self.ui.textEdit.toPlainText() self.ui.textEdit.clear() self.ui.textBrowser.append('User: '+text) self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.client.connect((self.HOST, self.PORT)) self.client.sendall(text.encode()) # Server message serverMessage = str(self.client.recv(1024), encoding='utf-8') self.ui.textBrowser.append('<font color="#FF0000">Server: '+serverMessage+'</font>') self.client.close() if __name__ == '__main__': app = QtWidgets.QApplication([]) window = MainWindow() window.show() sys.exit(app.exec_())
其實也沒有什麼好解說的地方,基本上跟我前一篇紀錄 Socket 該怎麼運作的文章一模一樣。
實際動起來的畫面如下:
跟許多 LineBot 教學的基本範例一樣會重複你寄送的內容。剩下該怎麼再去設計 ChatBot 聊天內容,就是大家各有想法了。