我是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