基于 Quercus 的手游项目终于上线了

经过半年的开发,我们第一款手游戏终于开发完毕,架构使用了 netty + Quercus 实现用 php 通过 websocket 与客户端通信。

项目上线近一个月,基本稳定。而且不存在性能方面问题,之前在内网测试,pc 机 4G 内存,在线 1000 人,没有卡动感觉。 这个数

字足以满足我们的需求, 想用 Quercus 大胆的用吧,到 4.0.39 应该会更完美,希望支持 Quercus 的多起来,与 hhvm 的火爆程度

真是是没法比。

java(android) rsa 实现与 php 服务端通信

rsa 密钥生成 见 http://blog.andsky.com/js-rsa-use-openssl-make-public-pirvate-key/

android 客户端用rsa 公钥加密后经 base64 编码发到 服务端,服务端使用私钥解密

客户端代码

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
import sun.misc.BASE64Encoder;



public class rsa {


	public static void main(String[] args) throws Exception {

		String modulus = "C34FF1FF9771ED88814C26905297BAEDCEC03B847D8AB5620848FC100AC0564FAD5364E9834E29118E7B5F8B1B9EAB201730C4860E8AF2ED2E028704105A01044501A9EF6DA2968E76273AAE496A0963A2FEA9B6179A86F28ACC61C087FB1AEEA4E1CB0ADBB9B757C303741DE602FD790953C8E2C004A425C7CAF4813F403DCD";
        String publicExponent = "010001";

        rsa key = new rsa();
        PublicKey publicKey = key.getPublicKey(modulus, publicExponent);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");


        //明文
        String tString = "aabbsdfsdf";
        byte[] plainText = tString.getBytes("UTF-8");
        //加密
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] enBytes = cipher.doFinal(plainText);
        System.out.println(new BASE64Encoder().encode( enBytes ));
	}


	 public PublicKey getPublicKey(String modulus,String publicExponent) throws Exception {
         BigInteger m = new BigInteger(modulus, 16);
         BigInteger e = new BigInteger(publicExponent, 16);
         RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m,e);
         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
         PublicKey publicKey = keyFactory.generatePublic(keySpec);
         return publicKey;

   }




}

服务端代码

 function privatekey_decodeing($crypttext, $privatekey)
    {

        $prikeyid = openssl_get_privatekey($privatekey);
        if (openssl_private_decrypt($crypttext, $sourcestr, $prikeyid,OPENSSL_PKCS1_PADDING))
        {
            return $sourcestr;
        }
        return FALSE;
    }

 $i = file_get_contents("private.key");

$base = 'fgvroFPT8GCIPYkGZJ834V0zQsnwbHKsCpFjpdN6TowUuxc6Bxu5PCF7SaZvb+3eCVEsuAjN73IP
QhRclqPiSv0MNPeZaYxNVPCDBkalsW3+/OuwPr7sQ53/rDwr2et0FnKJtkNyaFROMnxI9wRyg2Tx
h4+Fe60ypCvwY+wT8eg=';

	$b = base64_decode($base);
var_dump(privatekey_decodeing($b, $i));

quercus 4.0.38 发布

修正了不少bug 真是越来越完善了,赞一个

quercus: empty() needs to call ArrayAccess->offsetExists() (#5612, rep by G. Krall)
quercus: session_status() not implemented (#5609, rep by G. Krall)
quercus: self doesn’t work inside a namespace (#5608, G. Krall)
quercus: ReflectionParameter->getClass() not implemented (#5607, rep by G. Krall)
quercus: IllegalArgumentException vfs: not found on JBoss (#5606, rep by G. Krall)
quercus: ReflectionFunction does not work for closures (#5605, rep by G. Krall)
quercus: Xml reader is not working (#5603, rep by qumo)
quercus: call_user_func() needs to call __invoke (#5601, rep by G. Krall)
quercus: instanceof Closure returns false for closures (#5600, rep by G. Krall)
quercus: QuercusCompiledScript.eval() needs to return the Value object (#5589, rep by S. Guo)
quercus: ScriptEngineManager.getEngineByName(“php”) returns Quercus with unicode.semantics=off (#5588, rep by S. Guo)

php实现websocket手游架构设想

众所周知 php 的开发效率确实块。但在 socket 这块一直没有什么大的发展,设想用 两种方案用 php 实现 websocket game 开发

方案1 netty+quercus+php

方案2 Swoole + php

两种方案感觉都可行,quercus 近期更新力度很大,已经解决 mysql 乱码问题。 php 转成 java 测试性能确实不错

Swoole 是近期关注比较多的了,php 原生实现,作者更新速度很快,但缺少实际项目案例。

两种方案选择了 quercus ,感觉应该更稳定一些,实践中,期待项目上线测试效果

SWFUpload V2

Flash Player 10的安全机制更严格,类似打开文件上传的对话框的操作,一定需要用户交互才触发,如果用脚本触发,会报#2176的运行时错误。

void selectFile()
不赞成使用,不兼容Flash Player 10
弹出flash的文件选择对话框,只能选择单个文件。

void selectFiles()
不赞成使用,不兼容Flash Player 10
弹出flash的文件选择对话框,可一次性选择多个文件。

flash_width
固定值:1px
(v2.1.0已删除) 设置插入flash影片的HTML元素容器的宽度。如果此设置小于1像素,一些浏览器会出现功能异常。 因此该值在v2.1.0中删除了自定义设置,默认设置为1像素了。

flash_height
固定值:1px
(v2.1.0已删除) 设置插入flash影片的HTML元素容器的高度。如果此设置小于1像素,一些浏览器会出现功能异常。 因此该值在v2.1.0中删除了自定义设置,默认设置为1像素了。

flash_color
默认值:#FFFFFF
(v2.2.0已删除) 设置HTML页面中的flash背景色,默认为#FFFFFF

prevent_swf_caching
默认值:true
(v2.2.0新增)该布尔值设置是否在Flash URL后添加一个随机值,用来防止浏览器缓存了该SWF影片。这是为了解决一些基于IE-engine的浏览器上的出现一个BUG。

提醒:SWFUpload是直接在flash_url后添加了一个swfuploadrnd的随机参数。如果你给定的flash_url中已经存在了GET类型的参数,那么就会出现两个问号连接符导致错误。

button_placeholder_id
默认值:null
(v2.2.0新增) 该必要参数指定了swfupload.swf将要替换的页面内的DOM元素的ID值。当对应的DOM元素被替换为SWF元素时,SWF的容器会被添加一个名称为”swfupload”的样式选择器供CSS自定义使用。

button_image_url
默认值:空字符串
(v2.2.0新增) V2.2.0版最大的改变就是引入了一个按钮到SWF中,利用该参数可以设置一个相对于该swf文件或者是绝对地址的图片(或者是SWF),作为按钮的UI展现。所有FLASH支持的图片类型都可以使用(gif,jpg,png,或者是一个SWF)。
该按钮图片需要经过一定规则(CSS Sprite)的处理。按钮图片中需要包括按钮的4个状态,从上到下依次是normal, hover, down/click, disabled.(可以参照官方demo中的图片)

button_width
默认值:1
(v2.2.0新增) 设置该SWF的宽度属性。

button_height
默认值:1
(v2.2.0新增)设置该SWF的高度属性(按钮图片高度的1/4)

button_text
默认值:空字符串
(v2.2.0新增) 该属性设置Flash Button中显示的文字,支持HTML。HTML文本的样式可以通过CSS选择器并配合button_text_style参数来设置。关于Flash文本对HTML的支持详细可见 Adobe’s Flash documentation。

button_text_style
默认值:”color: #000000; font-size: 16pt;”
(v2.2.0新增)此参数配合button_text参数,可以通过CSS样式来设置Flash Button中的文字样式。关于Flash文本对CSS的支持详细可见Adobe’s Flash documentation

button_text_top_padding
默认值:0
(v2.2.0新增) 设置Flash Button上文字距离顶部的距离,可以使用负值。

button_text_left_padding
默认值:0
(v2.2.0新增) 设置Flash Button上文字距离左侧的距离,可以使用负值。

button_action
默认值:SWFUpload.BUTTON_ACTION.SELECT_FILES(多文件上传)
(v2.2.0新增) 设置Flash Button点击以后的动作。默认为SWFUpload.BUTTON_ACTION.SELECT_FILES,点击按钮将会打开多文件上传的对话框。如果设置为SWFUpload.BUTTON_ACTION.SELECT_FILE,则为单文件上传。如果设置为SWFUpload.BUTTON_ACTION.START_UPLOAD,则启动文件上传。

button_disabled
默认值:false
(v2.2.0新增) 该布尔值设置Flash Button是否是禁用状态。当它处于禁用状态的时候,点击不会执行任何操作。

button_cursor
默认值:SWFUpload.CURSOR.ARROW(箭头光标)

(v2.2.0新增) 此参数可以设置鼠标划过Flash Button时的光标状态。默认为SWFUpload.CURSOR.ARROW,如果设置为SWFUpload.CURSOR.HAND,则为手形

button_window_mode
默认值:SWFUpload.WINDOW_MODE.WINDOW
(v2.2.0新增) 此参数可以设置浏览器具体以哪种模式显示该SWF影片。

最后,SWFUpload v2在the Mac Flash Player上不能正常功能。

相关文档:
官方网站
http://www.swfupload.org/
官方文档
http://demo.swfupload.org/Documentation/
中文翻译
http://www.v-sky.com/doc/swfupload/Documentation.html

smarty 颜色选择框扩展


 * Name:     color_options
* Input:
* - name (optional) - string default "color" * - selected (optional) - string default not set * @author andsky * @param array * @param Smarty * @return string */ function smarty_function_color_options($params, &$smarty) { $name = empty( $params['name'] ) ? 'color' : $params['name']; $colors=array( "skyblue", "royalblue", "blue", "darkblue", "orange", "orangered", "crimson", "red", "firebrick", "darkred", "green", "limegreen", "seagreen", "teal", "deeppink", "tomato", "coral", "purple", "indigo", "burlywood", "sandybrown", "sienna", "chocolate", "silver" ); $_html_result = ''."\n"; foreach ($colors as $c){ $sel = ''; if ( isset($params['selected']) && $params['selected'] == $c ) { $sel = ' selected="selected"'; } $_html_result .= "\n"; } $_html_result = '' . "\n"; return $_html_result; } ?>

如何加密PHP文件 

由于安全原因,有些时候需要把PHP文件加密。zend是收费的软件,而且价格不菲,让人望尘莫及。这里介绍另一种加密方法:php-screw。
  php-screw是一款开源,免费,自由使用的软件,它不仅使用方便,而且可以自定义加密字符串,字符串的长度不受限制。下面这些操作是在Debian环境下实现的。
  1、下载软件包。到http://sourceforge.net/projects/php-screw/下载php-screw。下载得到的是tar包。
  2、安装必须的软件环境:apt-get install php5-dev php5
  3、把在第一步中得到的软件包解压:tar -zxvf php_screw-1.3.tgz
  4、进入解压缩后得到的目录:cd php_screw-1.3,然后执行命令:phpize生成一些配置安装文件。
  5、检查编译环境:
      ./configure    #检查编译环境
    自定义加密字符串,你据自己的意愿,修改文件my_screw.h内容,这里面主要记录的是加密字符串。
      make       #编译
  6、把文件modules/php_screw.so拷贝到/usr/lib/php5/2006*/目录下。
  7、修改文件/etc/php5/apache2/php.ini,在需要位置添加如下内容:
    extension=php_screw.so
  8、在WEB服务器的根目录里创建文件phpinfo.php,文件的内容如下:
    
  9、在浏览器里输入http:///phpinfo.php,看看php_screw是否生效。
  10、进入tools目录,执行命令:
    make
    生成文件screw。
  11、进入需要加密的PHP文件所在的文件夹,执行命令
    /full/path/of/screw .php
    这时的文件便被加密了,原来的文件被重新命名为:.php.screw。
  12、screw这个命令只支持单个文件的加密,不支持/full/path/of/screw *.php这种命令格式。如果需要把整个目录下的文件加密需要用如下命令:
    find . -name ‘*.php’ -exec /full/of/path/of/screw {} \;
  以上写的这些是在Debian环境下实现的,如果在window平台下,只要加载了php_screw这个模块,加密的文件也可以正常显示,但不能在windows平台下进行加密。
  好了,用php_screw加密php文件介绍完了。如果您对这个工具感兴趣,不防试一试。

转自 http://afericazebra.blog.163.com/blog/static/300504082008101902427449/

不错,freebsd 的port 也有,在 /usr/ports/www/php-screw ,正好用一下

利用Curl、socket、file_get_contents POST数据

array( 
            'method'=>'POST', 
            'header'=>'Content-type: application/x-www-form-urlencoded'."\r\n". 
                      'User-Agent : Jimmy\'s POST Example beta'."\r\n". 
                      'Content-length: '.strlen($post_string)+8, 
            'content'=>'mypost='.$post_string) 
         ); 
    $stream_context = stream_context_create($context); 
    $data = file_get_contents($remote_server,FALSE,$stream_context); 
     return $data; 
}

?> 

转自 http://hi.baidu.com/xsite/blog/item/1ae57963be3e38680d33fa6b.html

Nginx + PHP mysql_pconnect = Database errors (Too many connections)

If you’re using NGinx spawn-cgi or FPM with PHP and calling mysql_pconnect, you are likely going to experience frequent database crashes and “Too many connections” errors.

This took a while to trace, but once you understand the issue, it all makes sense.

mysql_pconnect opens a “persistent” connection to the database. From the documentation: “the connection to the SQL server will not be closed when the execution of the script ends. Instead, the link will remain open for future use (mysql_close() will not close links established by mysql_pconnect()).”

The issue is that FPM keeps a number of php-cgi processes running in the background to process php scripts. These php-cgi processes never die and so MySQL connections keep open forever…

Sooner or later, you are going to run out of MySQL connections (or worse yet – run out of file descriptors) and that’s when all hell breaks loose.

And if that’s not enough, after doing some digging into mysql_pconnect I found a few additional reasons NOT to use mysql_pconnect:

1. If you use mysql_pconnect on a machine that has a local database and you are connecting to a remote database, PHP will try to use the same mysql connection for both databases.

2. Temporary tables don’t work with persistent connections (they are only visible to the connection that was used to open the table)

3. Setting charset variables on a persistent connection, is going to impact all future queries on that connection as well

4. Calling mysql_pconnect twice (in the same script) with different parameters doesn’t work as expected

5. PHP 4.1 on Apache running with MySQL persistent connections, is known to memory leak (not flushing properly).

Bottom line, never ever use mysql_pconnect.

Replace all occurrences of mysql_pconnect with mysql_connect in your code and in your php.ini file, prevent persistent connections:

[MySQL] 
; Allow or prevent persistent links. 
mysql.allow_persistent = Off 

原文 http://www.softwareprojects.com/resources/programming/t-nginx-+-php-mysql_pconnect–database-errors-too-m-1751.html