<commit_before># encoding: UTF-8


########################################################################
import json
import sys

import ssl
import time
import websocket
from threading import Lock, Thread


class WebSocketClient(object):
    """
    Websocket API
    
    实例化之后，应调用start开始后台线程。调用start()函数会自动连接websocket。
    若要终止后台线程，请调用stop()。 stop()函数会顺便断开websocket。
    
    该类默认打包方式为json，若从服务器返回的数据不为json，则会触发onError。
    
    可以覆盖以下回调：
    onConnected
    onDisconnected
    onPacket        # 数据回调，只有在返回的数据帧为text并且内容为json时才会回调
    onError
    
    当然，为了不让用户随意自定义，用自己的init函数覆盖掉原本的init(host)也是个不错的选择。
    
    关于ping：
    在调用start()之后，该类每60s会自动发送一个ping帧至服务器。
    """
    
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        self.host = None  # type: str

        self.onConnected = self.defaultOnConnected
        self.onDisconnected = self.defaultOnDisconnected
        self.onPacket = self.defaultOnPacket
        self.onError = self.defaultOnError

        self.createConnection = websocket.create_connection
        
        self._ws_lock = Lock()
        self._ws = None  # type: websocket.WebSocket
        
        self._workerThread = None  # type: Thread
        self._pingThread = None  # type: Thread
        self._active = False

    #----------------------------------------------------------------------
    def setCreateConnection(self, func):
        """
        for internal usage
        :param func: a function like websocket.create_connection
        """
        self.createConnection = func

    #----------------------------------------------------------------------
    def init(self, host):
        self.host = host
    
    #----------------------------------------------------------------------
    def start(self):
        """启动"""
        self._connect()
        
        self._active = True
        self._workerThread = Thread(target=self._run)
        self._workerThread.start()
        
        self._pingThread = Thread(target=self._runPing)
        self._pingThread.start()
        
        self.onConnected()
        
    #----------------------------------------------------------------------
    def stop(self):
        """
        关闭
        @note 不能从工作线程，也就是websocket的回调中调用
        """
        self._active = False
        self._disconnect()

    #----------------------------------------------------------------------
    def sendPacket(self, dictObj):  # type: (dict)->None
        """发出请求:相当于sendText(json.dumps(dictObj))"""
        return self._get_ws().send(json.dumps(dictObj), opcode=websocket.ABNF.OPCODE_TEXT)<commit_msg>[Fix] 修复start后响应两次onConnected的错误<commit_after># encoding: UTF-8


########################################################################
import json
import sys

import ssl
import time
import websocket
from threading import Lock, Thread


class WebSocketClient(object):
    """
    Websocket API
    
    实例化之后，应调用start开始后台线程。调用start()函数会自动连接websocket。
    若要终止后台线程，请调用stop()。 stop()函数会顺便断开websocket。
    
    该类默认打包方式为json，若从服务器返回的数据不为json，则会触发onError。
    
    可以覆盖以下回调：
    onConnected
    onDisconnected
    onPacket        # 数据回调，只有在返回的数据帧为text并且内容为json时才会回调
    onError
    
    当然，为了不让用户随意自定义，用自己的init函数覆盖掉原本的init(host)也是个不错的选择。
    
    关于ping：
    在调用start()之后，该类每60s会自动发送一个ping帧至服务器。
    """
    
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        self.host = None  # type: str

        self.onConnected = self.defaultOnConnected
        self.onDisconnected = self.defaultOnDisconnected
        self.onPacket = self.defaultOnPacket
        self.onError = self.defaultOnError

        self.createConnection = websocket.create_connection
        
        self._ws_lock = Lock()
        self._ws = None  # type: websocket.WebSocket
        
        self._workerThread = None  # type: Thread
        self._pingThread = None  # type: Thread
        self._active = False

    #----------------------------------------------------------------------
    def setCreateConnection(self, func):
        """
        for internal usage
        :param func: a function like websocket.create_connection
        """
        self.createConnection = func

    #----------------------------------------------------------------------
    def init(self, host):
        self.host = host
    
    #----------------------------------------------------------------------
    def start(self):
        """启动"""
        self._connect()
        
        self._active = True
        self._workerThread = Thread(target=self._run)
        self._workerThread.start()
        
        self._pingThread = Thread(target=self._runPing)
        self._pingThread.start()
        
    #----------------------------------------------------------------------
    def stop(self):
        """
        关闭
        @note 不能从工作线程，也就是websocket的回调中调用
        """
        self._active = False
        self._disconnect()

    #----------------------------------------------------------------------
    def sendPacket(self, dictObj):  # type: (dict)->None
        """发出请求:相当于sendText(json.dumps(dictObj))"""
        return self._get_ws().send(json.dumps(dictObj), opcode=websocket.ABNF.OPCODE_TEXT)
{'fraction_non_alphanumeric': 0.2635556395238995, 'fraction_numerical': 0.0011335726431135461, 'mean_word_length': 1.4251030691708657, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4723942', 'n_tokens_mistral': 1576, 'n_tokens_neox': 1657, 'n_words': 233}