Skip to content

[Python] 使用 Socket 建立簡單的 ChatBot

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 聊天內容,就是大家各有想法了。

Tags:

Leave a Reply取消回覆

Exit mobile version