1<?php
2/**
3 * Tivoka - JSON-RPC done right!
4 * Copyright (c) 2011-2012 by Marcel Klehr <mklehr@gmx.net>
5 *
6 * MIT LICENSE
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 *
26 * @package  Tivoka
27 * @author Marcel Klehr <mklehr@gmx.net>
28 * @author Rafał Wrzeszcz <rafal.wrzeszcz@wrzasq.pl>
29 * @copyright (c) 2011-2012, Marcel Klehr
30 */
31
32namespace Tivoka\Client\Connection;
33use Tivoka\Exception;
34use Tivoka\Client\NativeInterface;
35use Tivoka\Client\Notification;
36use Tivoka\Client\Request;
37use Tivoka\Tivoka;
38
39/**
40 * JSON-RPC connection
41 * @package Tivoka
42 */
43abstract class AbstractConnection implements ConnectionInterface {
44
45    /**
46     * Initial timeout value.
47     * @var int
48     */
49    const DEFAULT_TIMEOUT = 5;
50
51    /**
52     * Timeot.
53     * @var int
54     */
55    protected $timeout = self::DEFAULT_TIMEOUT;
56
57    /**
58     * Connections options.
59     * @var array
60     */
61    protected $options = array();
62
63    public $spec = Tivoka::SPEC_2_0;
64
65    /**
66     * Sets the spec version to use for this connection
67     *
68     * @param string $spec The spec version (e.g.: "2.0")
69     *
70     * @return $this
71     */
72    public function useSpec($spec) {
73        $this->spec = Tivoka::validateSpecVersion($spec);
74        return $this;
75    }
76
77    /**
78     * Changes connection options.
79     * @param array $options
80     * @return $this Self reference.
81     */
82    public function setOptions($options) {
83        $this->options = $options;
84        return $this;
85    }
86
87    /**
88     * Changes timeout.
89     * @param int $timeout
90     * @return $this Self reference.
91     */
92    public function setTimeout($timeout)
93    {
94    	$this->timeout = $timeout;
95
96    	return $this;
97    }
98
99    /**
100     * Send a request directly
101     *
102     * @param string $method
103     * @param array $params
104     *
105     * @return Request
106     */
107    public function sendRequest($method, $params=null) {
108        $request = new Request($method, $params);
109        $this->send($request);
110        return $request;
111    }
112
113    /**
114     * Send a notification directly
115     * @param string $method
116     * @param array $params
117     */
118    public function sendNotification($method, $params=null) {
119        $this->send(new Notification($method, $params));
120    }
121
122    /**
123     * Creates a native remote interface for the target server
124     * @return NativeInterface
125     */
126    public function getNativeInterface()
127    {
128        return new NativeInterface($this);
129    }
130
131    /**
132     * Constructs connection handler.
133     * @param mixed $target Server connection configuration.
134     * @return ConnectionInterface
135     */
136    public static function factory($target)
137    {
138        // TCP conneciton is defined as ['host' => $host, 'port' => $port] definition
139        if (is_array($target) && isset($target['host'], $target['port'])) {
140            return new Tcp($target['host'], $target['port']);
141        } elseif (is_string($target) && preg_match('/^wss?:\/\//', $target)) {
142            // WebSocket URL starts with ws:// or wss://
143            return new WebSocket($target);
144        } else {
145            // HTTP end-point should be defined just as string
146            return new Http($target);
147        }
148    }
149}
150