Mika
Mika

Reputation: 1

In my python code I Cant Connect to an Openfire Server using slixmpp

In my python code I Cant Connect to an Openfire Server.

I want to connect to an OpenFire Server

my Code is

import threading
import tkinter as tk
from tkinter import simpledialog, scrolledtext
import json
import logging
import asyncio
from slixmpp import ClientXMPP

class EchoBot(ClientXMPP):
    def __init__(self, jid, password):
        super().__init__(jid, password)
        self.add_event_handler("session_start", self.start)
        self.add_event_handler("message", self.message)

    async def start(self, event):
        self.send_presence()
        await self.get_roster()

    async def message(self, msg):
        if msg['type'] in ('chat', 'normal'):
            msg.reply(f"Thanks for sending\n{msg['body']}").send(mto=msg['from'].boundjid.full)

class ChatApp:
    CONFIG_FILE = 'config.json'

    def __init__(self, root):
        self.root = root
        self.root.title("Chat Application")
        self.chat_client = None

        top_frame = tk.Frame(root)
        top_frame.pack(side=tk.LEFT, fill=tk.Y)

        self.change_server_button = tk.Button(top_frame, text="Other Server?", command=self.open_connect_dialog)
        self.change_server_button.pack(side=tk.TOP)

        self.search_bar = tk.Entry(top_frame, bd=1)
        self.search_bar.pack(padx=10, pady=10, side=tk.TOP)
        self.search_bar.bind("<KeyRelease>", self.filter_channels)

        self.channel_list = tk.Listbox(top_frame)
        self.channel_list.pack(fill=tk.BOTH, expand=True)

        self.all_channels = ["#Firma", "General", "Random", "Tech", "BLLLLLAAAAAAA"]
        for channel in self.all_channels:
            self.channel_list.insert(tk.END, channel)

        self.chat_display = scrolledtext.ScrolledText(root, wrap=tk.WORD, state=tk.DISABLED)
        self.chat_display.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)

        self.message_entry = tk.Entry(root, bd=1, width=100)
        self.message_entry.pack(padx=10, pady=10, fill=tk.X, side=tk.LEFT, expand=True)
        self.message_entry.bind("<Return>", self.send_message)

        self.send_button = tk.Button(root, text="Send", command=self.send_message)
        self.send_button.pack(padx=10, pady=10, side=tk.RIGHT)

        self.load_config()

    def filter_channels(self, event):
        search_term = self.search_bar.get().lower()
        self.channel_list.delete(0, tk.END)
        for channel in self.all_channels:
            if search_term in channel.lower():
                self.channel_list.insert(tk.END, channel)

    def open_connect_dialog(self):
        dialog = ConnectDialog(self.root, self.config)
        if dialog.result:
            server, jid, password, port = dialog.result
            self.config = {'server': server, 'jid': jid, 'password': password, 'port': port}
            self.save_config()
            self.connect_to_server(server, jid, password, port)

    def load_config(self):
        try:
            with open(self.CONFIG_FILE, 'r') as file:
                self.config = json.load(file)
        except (FileNotFoundError, json.JSONDecodeError):
            self.config = {
                'server': '',
                'jid': '',
                'password': '',
                'port': ''
            }

    def save_config(self):
        with open(self.CONFIG_FILE, 'w') as file:
            json.dump(self.config, file)

    def connect_to_server(self, server, jid, password, port):
        logging.basicConfig(level=logging.DEBUG, format='%(levelname)-8s %(message)s')
        self.chat_client = EchoBot(jid, password)
        addresse = tuple
        addresse = [server, port]
        try:
            # Verwende den richtigen Port und Server aus deiner Serverkonfiguration
            if self.chat_client.connect(addresse):
                # Starte die Schleife mit asyncio.run
                asyncio.run(self.chat_client.process(block=False))

                self.chat_client.starttls()

                self.chat_display.config(state=tk.NORMAL)
                self.chat_display.insert(tk.END, "Connected to server.\n")
                self.chat_display.config(state=tk.DISABLED)
            else:
                raise ConnectionError("Unable to connect.")
        except Exception as e:
            self.chat_display.config(state=tk.NORMAL)
            self.chat_display.insert(tk.END, f"Error: {str(e)}\n")
            self.chat_display.config(state=tk.DISABLED)
            logging.error(f"Error: {str(e)}")

    def display_message(self, message):
        self.chat_display.config(state=tk.NORMAL)
        self.chat_display.insert(tk.END, message)
        self.chat_display.config(state=tk.DISABLED)

    def send_message(self, event=None):
        message = self.message_entry.get()
        if message and self.chat_client:
            try:
                self.chat_client.send_message(mto=self.config['jid'], mbody=message, mtype='chat')
                self.display_message(f"Me: {message}\n")
                self.message_entry.delete(0, tk.END)
            except Exception as e:
                self.display_message(f"Send Error: {str(e)}\n")

class ConnectDialog(simpledialog.Dialog):
    def __init__(self, parent, config):
        self.config = config
        super().__init__(parent)

    def body(self, master):
        self.title("Connection Settings")

        tk.Label(master, text="Server Address:").grid(row=0)
        tk.Label(master, text="Username (JID):").grid(row=1)
        tk.Label(master, text="Password:").grid(row=2)
        tk.Label(master, text="Port:").grid(row=3)

        self.server_entry = tk.Entry(master)
        self.jid_entry = tk.Entry(master)
        self.password_entry = tk.Entry(master, show='*')
        self.port_entry = tk.Entry(master)

        self.server_entry.grid(row=0, column=1)
        self.jid_entry.grid(row=1, column=1)
        self.password_entry.grid(row=2, column=1)
        self.port_entry.grid(row=3, column=1)

        self.server_entry.insert(0, self.config['server'])
        self.jid_entry.insert(0, self.config['jid'])
        self.password_entry.insert(0, self.config['password'])
        self.port_entry.insert(0, str(self.config['port']))

        return self.server_entry

    def apply(self):
        server = self.server_entry.get()
        jid = self.jid_entry.get()
        password = self.password_entry.get()
        port = int(self.port_entry.get())
        self.result = (server, jid, password, port)

def main():
    root = tk.Tk()
    chat_app = ChatApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()

My DEBUG:

DEBUG    Using proactor: IocpProactor
DEBUG    Loaded Plugin: RFC 6120: Stream Feature: STARTTLS
DEBUG    Loaded Plugin: RFC 6120: Stream Feature: Resource Binding
DEBUG    Loaded Plugin: RFC 3920: Stream Feature: Start Session
DEBUG    Loaded Plugin: RFC 6121: Stream Feature: Roster Versioning
DEBUG    Loaded Plugin: RFC 6121: Stream Feature: Subscription Pre-Approval
DEBUG    Loaded Plugin: RFC 6120: Stream Feature: SASL
DEBUG    Event triggered: connecting
ERROR    Error: Unable to connect.

server Adress, Jid, password and port are Correct

Upvotes: 0

Views: 47

Answers (1)

Sergey Ponomarev
Sergey Ponomarev

Reputation: 3201

You need to enable logging of a connection error. With high chances there is required TLS by default but your server (local?) doesn't have the TLS enabled.

Check the slixmpp.connect() sources:

https://github.com/poezio/slixmpp/blob/7a0fb970833c778ed50dcb49c5b7b4043d57b1e5/slixmpp/clientxmpp.py#L140

See the force_starttls: bool = True param. It will not connect if the server doesn't have TLS enabled and rejects the START TLS command. So try to specify the param to False.

As a side recommendation check Gajim sources which is also written in Python.

Upvotes: 0

Related Questions