Как создать интернет чат на python
Перейти к содержимому

Как создать интернет чат на python

  • автор:

Консольный чат на Python. Реализация регистрации в чате

Прошу вашего совета. Я хочу реализовать простенький чат на python c одним условием — регистрацией «участников чата». (Ник участника чата можно зарезервировать под себя, и введя пароль — зайти в чат под своим ником) Саму логику обычного чата клиент-сервер я реализовал и проблем не возникало до тех пор, пока не появился процесс «регистрации» в чате. Логика работы:

- Соединение с сервером - Введение имени - Утверждение, что имя введено верно - Введение пароля - Повторное введение пароля - Пользователь заходит в общий чат 

Опишу проблему на словах: Не получается реализовать метод/принцип/логику, при котором при регистрации пользователя сервер слушал бы только сокеты от данного пользователя. Проще говоря, любые сокеты от прочих пользователей сбивают всю логику. Получается так: происходит регистрация пользователя №1 (любой этап), заходит пользователь №2 и сбивает регистрацию пользователю №1. Не могу понять, как создать «сессию» с определенным пользователем. Прошу помощи. Код привожу ниже: Код клиента:

import socket import threading SERVER_ADDRESS = ('localhost', 8125) sor = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sor.bind(('', 0)) sor.sendto(('Connect to server').encode('utf-8'), SERVER_ADDRESS) def reading_socket(): while True: data = sor.recv(1024) print(data.decode('utf-8')) potok = threading.Thread(target=reading_socket) potok.start() while True: message = input() sor.sendto((message).encode('utf-8'), SERVER_ADDRESS) 

Код сервера:

import socket SERVER_ADDRESS = ('localhost', 8125) server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_socket.bind(SERVER_ADDRESS) clients = [] members = <> print("Server is running") #ТУТ БОЛЬШАЯ ФУНКЦИЯ "РЕГИСТРАЦИИ" #С ВВОДОМ ИМЕНИ, ПОДТВЕРЖДЕНИЕМ, ПАРОЛЕМ def register_on_chat(port_address): register_data = 'Необходимо пройти регистрацию, введите свой ник: ' server_socket.sendto(register_data.encode('utf-8'), address) def confirm_nickname(port_address): name, address = server_socket.recvfrom(1024) registration_data = f"Ваш ник ? Введите Уes или No." server_socket.sendto(registration_data.encode('utf-8'), address) append_to_list(name, port_address) def new_nickmane(address): registration_data = 'Введите свой ник: ' server_socket.sendto(registration_data.encode('utf-8'), address) confirm_nickname(address) def append_to_list(name, port_address): data, address = server_socket.recvfrom(1024) if data.decode('utf-8') == 'Yes': get_pass(name) elif data.decode('utf-8') == 'No': new_nickmane(port_address) def get_pass(name): pass_data_1 = f"Привет Введите пароль для своего ника: " server_socket.sendto(pass_data_1.encode('utf-8'), address) password_1, adr= server_socket.recvfrom(1024) pass_data_2 = "Повтори пароль" server_socket.sendto(pass_data_2.encode('utf-8'), address) password_2, adr = server_socket.recvfrom(1024) if password_1 == password_2: members[name.decode('utf-8')] = password_1.decode('utf-8') pass_data_3 = "Отлично, регистрация прошла успешно" server_socket.sendto(pass_data_3.encode('utf-8'), address) print(members) else: pass_data_4 = "Давай-ка попробуем снова" server_socket.sendto(pass_data_4.encode('utf-8'), address) get_pass(name) confirm_nickname(port_address) while True: data, address = server_socket.recvfrom(1024) print(address[0], address[1]) if address not in clients: clients.append(address) register_on_chat(address) text = "Регистрация прошла успешно. Добро пожаловать в чат!" server_socket.sendto(text.encode('utf-8'), address) for client in clients: if client == address: text_from_client = data.decode('utf-8') print(text_from_client) continue server_socket.sendto(data, client) 

Как создать интернет чат на python

Блог веб разработки статьи | видеообзоры | исходный код

webfanat вконтакте webfanat youtube

Общий чат на python

Общий чат на python

Приветствую вас дорогие друзья! Сегодня мы напишем общий чат на python используя вебсокеты, а также познакомимся c WebSocket API в javascript. Погнали!

При разработке я буду использовать версию python 3.5, также понадобятся пакеты asyncio и websockets.

asyncio пакет предустановлен в python 3.5, он отвечает за асинхронное программирование.

websockets служит для работы с вебсокетами и его придется установить к примеру через утилиту pip.

Установка в linux имеет такой вид:

sudo pip3 install websockets

Далее по архитектуре будет всего два файла socket.html и my_socket.py.

Следовательно в socket.html будет клиентская часть, а в my_socket.py серверная.

В my_socket.py напишем.

import asyncio import websockets async def socket(websocket, path): print(websocket, path) start_server = websockets.serve(socket, '127.0.0.1', 5678) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()

В верхней части кода идет подключение пакетов asyncio и websockets. Далее мы создаем асинхронную функцию socket которая принимает два параметра — новое подключение(websocket) и относительный путь(path). Обратите внимание что асинхронные функции пишутся через приставку async. В теле функции просто выводятся значения параметров в консоль.

Затем создается сервер websockets:

start_server = websockets.serve(socket, '127.0.0.1', 5678)

Здесь указывается вызов нашей функции socket, адрес хоста(127.0.0.1) стандартный localhost и порт 5678.

Завершающим этапом идет асинхронный запуск сервера.

asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()

Пробуем запустить my_socket.py, результатом должно стать зависание в консоли, это значит что сервер ждет активных подключений для их обработки.

Для того чтобы создать новое подключение необходимо обратится к серверу по специальному протоколу ws — websocket. Делать мы это будем на javascript через специальный API websocket.

В файле socket.html пишем:

     Работа с сокетами на python    

Для работы с websocket api создаем объект socket через класс new WebSocket(). В самом классе указывается адрес соединения через протокол ws. Если сервер запущен под https то пишется так wss.

Событие open (onopen) срабатывает когда соединение открыто(установлено), error (onerror) когда происходит ошибка при подключении.

Теперь проверяем! Запускаем файл my_socket.py (наш сервер) и затем после этого открываем файл socket.html в любом браузере поддерживающим стандарты html5.

В консоли браузера должно быть сообщение о результате соединения. Если все хорошо то выведется ‘Соединение установлено’. В консоли интерпретатора Python выведется что то подобное:

То есть это вывод нового подключения и пути.

При открытии socket.html в новой вкладке, окне или даже просто перезагрузке страницы у нас всегда будет создаваться новое подключение. Проверить это вы опять же сможете через консоль Python.

Далее нужно будет записывать подключения всех пользователей для возможности рассылки сообщения по всем подключениям. Расширяем код!

import asyncio import websockets USERS = set() async def addUser(websocket): USERS.add(websocket) async def removeUser(websocket): USERS.remove(websocket) async def socket(websocket, path): await addUser(websocket) print(len(USERS), USERS) start_server = websockets.serve(socket, '127.0.0.1', 5678) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()

Здесь в дополнение создается множество ‘USERS’ и две функции:

async def addUser(websocket): USERS.add(websocket)

addUser() — функция добавляет подключение в множество.

async def removeUser(websocket): USERS.remove(websocket)

removeUser(websocket) — функция удаляет подключение из множества. Она будет вызываться когда подключение с пользователем будет не возможно(пользователь закрыл страницу, или провис интернет).

Обратите что функции являются асинхронными и будут вызываться через ключевое слово await.

addUser() вызывается при создании нового подключения. После вызова делаем вывод количества элементов в множестве и его содержимое. Процесс удаления подключения рассмотрим далее.

Теперь запустив сервер и перейдя на клиентскую страницу при каждом новом подключении мы сможем просматривать изменение содержимого множества ‘USERS’. С каждым новым подключением оно будет наполняться.

Подходим к завершающему этапу, а именно возможности отправки сообщения по всем подключениям и их удалению при невозможности установления соединения.

import asyncio import websockets USERS = set() async def addUser(websocket): USERS.add(websocket) async def removeUser(websocket): USERS.remove(websocket) async def socket(websocket, path): await addUser(websocket) try: while True: message = await websocket.recv() await asyncio.wait([user.send(message) for user in USERS]) finally: await removeUser(websocket) start_server = websockets.serve(socket, '127.0.0.1', 5678) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()

Здесь в функции socket() в которой создается новое подключение мы в дополнении пишем исключение (try/finally). В теле исключения try запускается бесконечный цикл while(true) в котором мы отслеживаем поступление новых сообщений на канал через метод recv() подключения websocket.

message = await websocket.recv()

При поступлении сообщения на канал оно помещается в переменную ‘message’ и затем отправляется каждому подключению(пользователю).

await asyncio.wait([user.send(message) for user in USERS])

Через данную конструкцию происходит обратная отправка сообщения каждому из записанных в множество ‘USERS’ подключений. То есть происходит некая рассылка сообщения по всем активным подключениям на клиентскую часть пользователя. Если соединение с одним из подключений не активно происходит ошибка и мы попадаем в блок finally где неактивное соединение удаляется из общего множества ‘USERS’.

await removeUser(websocket)

На клиентской части реализуем механизм отправки и приема сообщений:

     Работа с сокетами на python    

Добавляем теги div с классом ‘message’ куда будут добавляться новые сообщения и поле textarea откуда отправляться.

Вешаем обработчик ‘keyup’ на текстовую область. Обратите внимание что обработчик создан в событии onopen. Это важно! Так как метод send() объекта WebSocket API может быть вызван только после инициализации соединения с сервером. Отправка сообщения происходить по нажатию клавиши Enter, пустые сообщения отправлять нельзя.

socket.send(this.value.trim());

Метод send объекта websocket api отправляет данные на сервер, после чего идет очистка текстовой области.

Для приема сообщений с сервера отлавливается событие onmessage.

var p = ""; socket.onmessage = function(e)< p = document.createElement("p"); p.innerHTML = e.data; document.querySelector(".message").appendChild(p); >;

В событии возвращается объект с ключом ‘data’ где лежит наше сообщение. Оно просто помещается в сгенерированный тег ‘p’ который добавляется в блок div.message.

Проверяем! Запускаем сервер my_socket.py. Открываем клиентскую страницу socket.html по возможности в двух разных браузерах. И пробуем через текстовое поле добавить новых сообщений. В результате мы сможем наблюдать переписку между двумя браузерами. Если вы запустите чат на своем хостинге или сервере, то у вас появится возможность вести переписку на клиентской странице между пользователями в сети.

Вот в общем то и все. Сегодня мы реализовали простой общий чат на python и заодно поработали с websocket api. При этом написали не так уж много кода, за это спасибо питону. Надеюсь вам данная статья понравилась.

Подписывайтесь в мою группу Вконтакте чтобы получать новости о новых статьях и разработках. Также у меня есть небольшой канал youtube где вы сможете найти дополнительный материал.

Всем спасибо за внимание!

Оцените статью:
Статьи
  • localstorage HTML
  • map js
  • contenteditable HTML
  • Работа с выделением текста и курсором.
  • transform CSS
  • tkinter события
  • произношение javascript
  • Коллекции javascript
  • Асинхронные функции в javascript

Как создать чат-приложение на Python

Комната для чата — это интерфейс, который позволяет двум или более людям общаться в чате и отправлять сообщения всем, кто находится в комнате. Сегодня мы поговорим про то, как создать простое чат-приложение на Python и разрешить нескольким клиентам подключаться к нему с помощью сокетов.

Мы используем встроенный в Python сокет-модуль. Он дает возможность осуществлять операции с сокетами. Эти операции широко используются в Интернете: они стоят за любым подключением к любой сети.

Кроме того, для изменения цвета текста, нам понадобится пакет colorama. С помощью этого пакета мы сможем присвоить цвет каждому клиенту в нашем чате. Давайте установим этот модуль:

pip3 install colorama

Поскольку мы используем сокеты, нам нужен серверный и клиентский код. Давайте начнем с серверной части.

Серверная часть

В нашей архитектуре вся работа сервера заключается в выполнении двух основных операций:

  • Прослушивание клиентских подключений. Если подключается новый клиент, мы добавляем его в нашу коллекцию клиентских сокетов
  • Запуск нового потока для каждого подключенного клиента, прием сообщений, отправленных от клиента, и трансляция их всем другим пользователям.

Приведенный ниже код создает TCP-сокет и привязывает его к адресу сервера, а затем прослушивает поступающие соединения:

import socket from threading import Thread # server's IP address SERVER_HOST = "0.0.0.0" SERVER_PORT = 5002 # port we want to use separator_token # we will use this to separate the client name & message # initialize list/set of all connected client's sockets client_sockets = set() # create a TCP socket s = socket.socket() # make the port as reusable port s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # bind the socket to the address we specified s.bind((SERVER_HOST, SERVER_PORT)) # listen for upcoming connections s.listen(5) print(f"[*] Listening as :")

Обратите внимание, что мы использовали 0.0.0.0 в качестве IP-адреса сервера. Это охватывает все адреса IPv4 на локальном компьютере. Вы можете задаться вопросом, почему мы просто не используем localhost или 127.0.0.1. У сервера может быть два IP адреса, допустим 192.168.1.2 в одной сети и 10.0.0.1 в другой. При указании адреса 0.0.0.0 сервер слушает обе сети.

Мы еще не принимаем соединения, так как не вызывали метод accept() . Приведенный ниже код завершает наш бэкенд:

def listen_for_client(cs): """ This function keep listening for a message from `cs` socket Whenever a message is received, broadcast it to all other connected clients """ while True: try: # keep listening for a message from `cs` socket msg = cs.recv(1024).decode() except Exception as e: # client no longer connected # remove it from the set print(f"[!] Error: ") client_sockets.remove(cs) else: # if we received a message, replace the # token with ": " for nice printing msg = msg.replace(separator_token, ": ") # iterate over all connected sockets for client_socket in client_sockets: # and send the message client_socket.send(msg.encode()) while True: # we keep listening for new connections all the time client_socket, client_address = s.accept() print(f"[+] connected.") # add the new connected client to connected sockets client_sockets.add(client_socket) # start a new thread that listens for each client's messages t = Thread(target=listen_for_client, args=(client_socket,)) # make the thread daemon so it ends whenever the main thread ends t.daemon = True # start the thread t.start()

Как упоминалось ранее, мы добавляем подключенный клиентский сокет в коллекцию наших сокетов. Затем запускаем новый поток и устанавливаем его как поток демона (daemon thread), который выполняет определенную нами функцию listen_for_client() . При наличии клиентского сокета эта функция ожидает отправки сообщения с помощью метода recv() и затем отправляет это сообщение всем другим подключенным клиентам.

Наконец, давайте закроем все сокеты:

# close client sockets for cs in client_sockets: cs.close() # close server socket s.close()

Хорошо, с серверным кодом покончено, теперь давайте углубимся в код клиентской части.

Клиентская часть

Клиент выполняет три основные операции:

  • Подключение к серверу
  • Прослушивание сообщений, поступающих с сервера и вывод их на консоль (чтобы от сервера поступило сообщение, клиент должен отправить его на сервер, а сервер — распространить)
  • Ожидание сообщений от пользователей для их дальнейшей отправки на сервер.

Ниже представлен код для первой операции:

import socket import random from threading import Thread from datetime import datetime from colorama import Fore, init, Back # init colors init() # set the available colors colors = [Fore.BLUE, Fore.CYAN, Fore.GREEN, Fore.LIGHTBLACK_EX, Fore.LIGHTBLUE_EX, Fore.LIGHTCYAN_EX, Fore.LIGHTGREEN_EX, Fore.LIGHTMAGENTA_EX, Fore.LIGHTRED_EX, Fore.LIGHTWHITE_EX, Fore.LIGHTYELLOW_EX, Fore.MAGENTA, Fore.RED, Fore.WHITE, Fore.YELLOW ] # choose a random color for the client client_color = random.choice(colors) # server's IP address # if the server is not on this machine, # put the private (network) IP address (e.g 192.168.1.2) SERVER_HOST = "127.0.0.1" SERVER_PORT = 5002 # server's port separator_token # we will use this to separate the client name & message # initialize TCP socket s = socket.socket() print(f"[*] Connecting to :. ") # connect to the server s.connect((SERVER_HOST, SERVER_PORT)) print("[+] Connected.")

Заодно мы устанавливаем цвет для каждого клиента (увидеть можно будет в выводе). Кроме того, давайте установим имя для каждого клиента, чтобы мы могли различать клиентов между собой:

# prompt the client for a name name = input("Enter your name: ")

Отлично, двигаемся дальше! Приведенный ниже код отвечает за вторую операцию — прослушивание сообщений с сервера и вывод их на консоль:

def listen_for_messages(): while True: message = s.recv(1024).decode() print("\n" + message) # make a thread that listens for messages to this client & print them t = Thread(target=listen_for_messages) # make the thread daemon so it ends whenever the main thread ends t.daemon = True # start the thread t.start()

Кроме того, мы хотим, чтобы прослушивание сообщений происходило в фоне, т.е. чтобы этот поток был потоком-демоном.

Переходим к последней операции — ожиданию сообщений от пользователей с последующей отправкой их на сервер. Сделаем это следующим образом:

while True: # input message we want to send to the server to_send = input() # a way to exit the program if to_send.lower() == 'q': break # add the datetime, name & the color of the sender date_now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') to_send = f"[] " # finally, send the message s.send(to_send.encode()) # close the socket s.close()

Мы добавляем цвет для каждого клиента, его имя, а также текущую дату и время к отправляемому сообщению. Дальше мы отправляем сообщение с помощью метода send() . Для выхода из программы нужно будет ввести «q» в качестве сообщения.

Демонстрация функционала

Хорошо, теперь, когда мы закончили и серверную, и клиентскую часть, давайте проверим, как всё работает. Во-первых, давайте запустим один экземпляр сервера:

Круто, сервер мониторит предстоящие подключения клиентов, давайте попробуем запустить один экземпляр клиента:

Отлично! Первый клиент подключен к серверу и ему предлагается ввести имя пользователя. Теперь, чтобы убедиться, что он подключен, вернитесь к консоли сервера:

Обратите внимание, что сейчас мы используем адрес localhost (127.0.0.1), так как это одна и та же машина. Но если вы хотите подключиться с других машин в той же сети, вы также можете это сделать, просто измените SERVER_HOST в клиентской части кода с 127.0.0.1 на частный IP-адрес сервера.

Давайте запустим еще один клиент, чтобы они могли поболтать:

Удивительно! Как видите, сообщения клиентов отличаются цветом, что позволяет различать пользователей. Что ж, давайте запустим третьего клиента для развлечения:

Заключение

Отлично, теперь каждое сообщение, отправленное одним клиентом, отправляется всем остальным. Обратите внимание, что цвета меняются при каждом повторном выполнении сценария client.py.

Пожалуйста, сверьтесь с полным кодом, чтобы вы могли легко запустить чат-приложение самостоятельно!

Мы также советуем добавить больше возможностей в эту программу. Например, можно сделать оповещение для всех пользователей при подключении нового клиента!

Итак, сегодня мы поговорили о том, как создать чат-приложение на Python. Надеемся, данная статья была вам полезна!

Успехов в написании кода!

Как создать онлайн чат на Python?

Я нашёл множество гайдов, но во всех них, рассказывают про локальную сеть. Я хочу создать хост на пк либо на сервере в интернете. В чате можно будет общаться с людьми из другого города или района. Кто может подсказть хороший гайд? (Либо сами его составить)
. забыл упомянуть чат будет без интерфейса и пользоваться им нужно через CMD

  • Вопрос задан более двух лет назад
  • 398 просмотров

3 комментария

Средний 3 комментария

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *