package xmpp import ( "bytes" "encoding/xml" "errors" "fmt" "net" "strings" ) type Client struct { // Store user defined options options Options // Session gather data that can be accessed by users of this library Session *Session // TCP level connection / can be replace by a TLS session after starttls conn net.Conn } /* Setting up the client / Checking the parameters */ // TODO: better options check func NewClient(options Options) (c *Client, err error) { // TODO: If option address is nil, use the Jid domain to compose the address if options.Address, err = checkAddress(options.Address); err != nil { return } if options.Password == "" { err = errors.New("missing password") return } c = new(Client) c.options = options // Parse JID if c.options.parsedJid, err = NewJid(c.options.Jid); err != nil { return } return } func checkAddress(addr string) (string, error) { var err error hostport := strings.Split(addr, ":") if len(hostport) > 2 { err = errors.New("too many colons in xmpp server address") return addr, err } // Address is composed of two parts, we are good if len(hostport) == 2 && hostport[1] != "" { return addr, err } // Port was not passed, we append XMPP default port: return strings.Join([]string{hostport[0], "5222"}, ":"), err } // NewClient creates a new connection to a host given as "hostname" or "hostname:port". // If host is not specified, the DNS SRV should be used to find the host from the domainpart of the JID. // Default the port to 5222. func (c *Client) Connect() (*Session, error) { var tcpconn net.Conn var err error if tcpconn, err = net.Dial("tcp", c.options.Address); err != nil { return nil, err } c.conn = tcpconn if c.conn, c.Session, err = NewSession(c.conn, c.options); err != nil { return c.Session, err } // We're connected and can now receive and send messages. //fmt.Fprintf(client.conn, "%s%s", "chat", "Online") fmt.Fprintf(c.Session.socketProxy, "") return c.Session, err } func (c *Client) recv(receiver chan<- interface{}) (err error) { for { _, val, err := next(c.Session.decoder) if err != nil { return err } receiver <- val val = nil } panic("unreachable") } // Channel allow client to receive / dispatch packets in for range loop func (c *Client) Recv() <-chan interface{} { ch := make(chan interface{}) go c.recv(ch) return ch } // Send sends message text. func (c *Client) Send(packet string) error { fmt.Fprintf(c.Session.socketProxy, packet) return nil } func xmlEscape(s string) string { var b bytes.Buffer xml.Escape(&b, []byte(s)) return b.String() }