GTK百老汇支持同时连接



我是GTK Broadway的新手,我成功地创建了一个运行在它下面的gedit实例。我可以使用任何浏览器和http://localhost:8080访问该界面,但我不能在同一地址上打开两个不同的选项卡。当我尝试从另一个选项卡连接时,前一个会断开连接。

我想做的是创建一个服务器,在一侧运行GTK应用程序,并为多个用户提供该应用程序,他们将能够可视化GUI和正在发生的事情,但只有一个用户能够交互(我正在处理它)。

编辑:我想了一个解决方案,服务器用Websockets和HTML5 Canvas加载页面,然后充当代理,向客户端提供相同的内容,然后代理处理来自客户端的传入输入(并管理并行连接)。这在技术上可行吗?

提前谢谢。

我在回程机器上发现了这个:

百老汇透明代理(Gtk3/HTML5后端)

幸运的是,源代码可以在回溯机器上恢复:

#!/usr/bin/perl
#
# Peteris Krumins (peter@catonmat.net)
# http://www.catonmat.net  --  good coders code, great reuse
#
# A simple TCP proxy that implements IP-based access control
# Currently the ports are hard-coded, and it proxies
# 0.0.0.0:1080 to localhost:55555.
#
# Written for the article "Turn any Linux computer into SOCKS5
# proxy in one command," which can be read here:
#
# http://www.catonmat.net/blog/linux-socks5-proxy
#
##############################################################
#
# Modified by Dan Kasak ( d.j.kasak.dk@gmail.com )
# http://tesla.duckdns.org
#
# Added some hacks for proxying based on the value in a cookie,
# as a proof-of-concept transparent proxy for Gtk+ / broadway
use warnings;
use strict;
use Data::Dumper;
use IO::Socket;
use IO::Select;
my $ioset = IO::Select->new;
my %socket_map;
my $debug = 0;
sub new_server {
    my ($host, $port) = @_;
    my $server = IO::Socket::INET->new(
        LocalAddr => $host,
        LocalPort => $port,
        ReuseAddr => 1,
        Listen    => 100
    ) || die "Unable to listen on $host:$port: $!";
}
sub close_connection {
    my $client = shift;
    my $client_ip = client_ip($client);
    my $remote = $socket_map{$client};
    
    foreach my $socket ( $client , $remote ) {
        
        if ( ref $socket eq 'ConnectionFuture' ) {
            $socket->disconnect;
        } else {
            $ioset->remove( $socket );
        }
    }
    delete $socket_map{$client};
    delete $socket_map{$remote};
    $client->close;
    $remote->close;
    print "Connection from $client_ip closed.n" if $debug;
}
sub client_ip {
    my $client = shift;
    return inet_ntoa($client->sockaddr);
}
print "Starting a server on 0.0.0.0:10666n";
my $server = new_server('0.0.0.0', 10666);
$ioset->add($server);
while (1) {
    for my $socket ($ioset->can_read) {
        if ($socket == $server) { # $socket is what we're reading from ... $server is our listener. if socket == server, we're reading, and need to create a new target
            ConnectionFuture->new( $server );
        }
        else {
            next unless exists $socket_map{$socket};
            my $remote = $socket_map{$socket};
            my $buffer;
            my $read = $socket->sysread($buffer, 4096);
            if ($read) {
                $remote->syswrite($buffer);
            }
            else {
                close_connection($socket);
            }
        }
    }
}
package ConnectionFuture;
use HTTP::Request;
sub new {
    
    my ( $class, $server ) = @_;
    
    my $self = {
        server  => $server
    };
    
    bless $self, $class;
    
    $self->{client} = $self->{server}->accept;
    
    $socket_map{ $self->{client} } = $self;
    $socket_map{ $self->{server} } = $self->{client};
    
    $ioset->add( $self->{client} );
    
    return $self;
    
}
sub syswrite {
    
    my ( $self, $buffer ) = @_;
    
    if ( ! exists $self->{remote} ) {
        
        my $host = 'localhost';
        
        my $request = HTTP::Request->parse( $buffer );
        
        my $headers = $request->headers;
        my $cookies = $headers->{cookie};
        
        print "Cookies:n" . $cookies . "n";
        
        my $port;
        
        if ( $cookies =~ /port=(w*)/ ) {
            
            $port = $1;
            
        } elsif ( $cookies = 'cookie1=test' ) {
            
            $port = 10000;
            
        }
        
        if ( $port ) {
            
            $self->{remote} = IO::Socket::INET->new(
                PeerAddr => $host
              , PeerPort => $port
            ) || die "Unable to connect to $host:$port: $!";
            
            $socket_map{ $self->{remote} } = $self->{client};
            
            $ioset->add( $self->{remote} );
            
        }
        
    }
    
    if ( $self->{remote} ) {
        $self->{remote}->syswrite( $buffer );
    }
    
}
sub disconnect {
    
    my $self = shift;
    
    $ioset->remove( $self->{client} );
    $ioset->remove( $self->{remote} );
    
}
sub close {
    
    my $self = shift;
    
    $self->{client}->close;
    
    if ( $self->{remote} ) {
        $self->{remote}->close;
    }
    
}
1;

希望它能帮助

编辑:幸运的是Dan创建了一个github repo,刚刚找到它:https://github.com/dankasak/broadway_proxy

最新更新