Websocket: страница, которая постоянно получает данные через веб-сокет с сервера, не может быть несколько раз

server.py использует бутылку в качестве веб-фреймворка и Bottle_websocket для отправки данных с периодом в 1 секунду во внешний интерфейс, который представляет собой html-страницу, которая обновляется и создает график в реальном времени по мере поступления данных в код javascript. У меня есть три сценария:

  1. Когда страница простаивает, я имею в виду, что когда данные не отправляются с сервера через веб-сокет, я могу открыть несколько вкладок в своем браузере.
  2. Когда на локальном хосте: адрес 8001 работает только один клиент, который получает данные из веб-сокета, я не могу открыть другую вкладку (я не могу начать с другого клиента)
  3. Когда в браузере уже открыто несколько вкладок и когда я начинаю получать данные только от одного клиента, все клиенты обновляются.

мое содержимое server.py выглядит следующим образом

from bottle import get,template,run,route,Bottle,static_file
from bottle import get,template,run,route,Bottle,static_file
from bottle.ext.websocket import GeventWebSocketServer
from bottle.ext.websocket import websocket
import random
import time

users = set()
@get('/')
def mainIndex():
    return template('indexStackoverflow')

@get('/websocket', apply=[websocket])
def chat(ws):
     users.add(ws)
     i = 0
     while i < 20:
         msg = ws.receive()
         speed = random.randrange(0,1000)
         i = i + 1      
         if msg is not None:
              for u in users:
                   u.send(str(speed))        
         else:
            print "msg is NONe is guesse"
            break
         time.sleep(1)    
    for u in users:
        u.close()
    users.remove(ws)
    ws.close()

@route('/js/<filename:path>')
def static(filename):
    return static_file(filename,root='js/')

run(host='0.0.0.0',port=8001,server=GeventWebSocketServer)

и содержимое indexStackoverflow.html

        var margin = {top:5, right: 10, bottom: 10, left: 70},
            width = 1200 - margin.left - margin.right,
            height = 250 - margin.top - margin.bottom;

        var data1;
        var x,y1,xAxis1,yAxis1,update;
        var duration = 1000;
	var moveDuration = 1000;
        // Parse the date / time
                var totalSeconds = 60;
                var n = 10;//totalSeconds;
		var limit = n;
                duration = 800;
                x = d3.time.scale()
                           .domain([0, ((n - 1) * duration)])
                           .range([0, width]);
        var valueline1 = d3.svg.line()
                .x(function(d,i) { return x(i*duration); })
                .y(function(d,i) { return y1(d); })
                .interpolate("monotone");

   // Set the ranges
                data1 = [0];
                

                y1 = d3.scale.linear().range([height, 0])
                                        .domain([0,1000]);
               xAxis1 =d3.svg.axis().scale(x)
                                .orient("bottom")
                                .ticks(d3.time.seconds, 1.0)
                                .tickFormat(d3.time.format('%M:%S'))
                                .innerTickSize(-height);
                yAxis1 = d3.svg.axis().scale(y1)
                        .innerTickSize(-width)
                        .outerTickSize(0)
                        .tickPadding(10)
                        .orient("left").ticks(10);
 		var svg = d3.select("#graph1")
                        .append("svg")
                        .attr("width", width + margin.left + margin.right)
                        .attr("height", height + margin.top + margin.bottom)
                        .append("g")
                        .attr("transform","translate(" + margin.left + "," + margin.top + ")");
               svg.append("defs").append("clipPath")
		    .attr("id", "clip")
		    .append("rect")
		    .attr("width", width)
		    .attr("height", height); 
                
		var xAxisLine= svg.append("g")                     // Add the X Axis
                        .attr("class", "x axis")
                        .attr("transform", "translate("+width+"," + height + ")")
                        .call(xAxis1);
		
		svg.append("g")                     // Add the Y Axis
                        .attr("class", "y axis")
                        .call(yAxis1)
			;

                var path = svg.append("g")
                                .attr("clip-path","url(#clip)")
                                .append("path")
                                .data(data1)
                                .attr("class", "line")
				.attr("d",valueline1(data1))
                                .attr("transform", "translate(" + (width )+")")
				;          // Add the valueline path.
	var random = d3.random.normal(0, 50);
	var  i = 0;
	var shifter = 0;
       function update(val){
                var svg1 = d3.select("#graph1");
                i = i + 1;
                shifter = 0;
                var val = JSON.parse(val);
               	data1.push(val); 

                if(i >= limit){
                        shifter = x(-duration);
                        svg.select(".line")
				.attr("d", valueline1(data1))
				.attr("transform","")
				.transition()
                                .duration(moveDuration)
                                .ease("linear")
                                .attr("transform","translate("+(shifter)+")")
                                ;

                        var x_axis_scale = d3.time.scale()
                                                .domain([(i+1-limit)*duration,((n-1+(i+1-limit))*duration)])
                                                .range([0,width]);
                        svg.select(".x.axis")
				.attr("transition",null)
                                .transition()
                                .duration(moveDuration)
                                .ease("linear")
					.call(d3.svg.axis().scale(x_axis_scale)
					.orient("bottom")
                                	.ticks(d3.time.seconds, 1.0)
                                	.tickFormat(d3.time.format('%M:%S'))
                                	.innerTickSize(-height)
				);
                        data1.shift();
                }
                else{
                        shifter = width - x(i*duration);
                        svg.select(".x.axis")
                               .transition()
                                .duration(moveDuration)
                               .ease("linear")
                                .attr("transform","translate("+(shifter)+","+(height)+")");
                        
			svg.select(".line")   // change the line
                                .attr("d", valueline1(data1))
                                .transition()
                                .duration(moveDuration)
                                .ease("linear")
                                .attr("transform","translate("+(shifter)+")")
                                ;
                        }
        }
var  ws = new WebSocket('ws://127.0.0.1:8001/websocket')
ws.onopen = function(evt) {
}

ws.onmessage = function(evt) {
	//alert(evt.data)       
	update(evt.data);
	ws.send("arrived");
}
$('#startBtn').submit(function() {
	ws.send("Pressed");
});
<!DOCTYPE html>
<meta charset="utf-8">
<style>

svg {
  font: 10px sans-serif;
}

.line {
  fill: none;
  stroke: #000;
  stroke-width: 1.5px;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

</style>
<body>
    <form id="startBtn">
            <input type="submit" value="Start Real" />
    </form>
<div id = "graph1"></div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script type="text/javascript" src="js/websocketStackoverflow.js"></script>

а файл websocketStackoverflow.js находится в папке js. Для запуска сервера сначала запустите на терминале python server.py

Я буду очень рад за ваши любые рекомендации/советы по преодолению этой проблемы.


person Upol Ryskulova    schedule 03.11.2015    source источник