RabbitMQ使用https/web-stomp

JS连接RabbitMQ在上篇中就已经实现了,但是发现在生产环境中无法使用,主要问题是通过https访问网站的话web-stomp也得支持ssl的安全访问,不支持ssl的话会因为安全问题无法进行访问。现将实现步骤记录一下。

  1. 首先得有ssl证书,可以去阿里云或者腾讯云申请免费的证书
  2. 申请好后将ssl证书下载下来,处理一下,下载下来是两个文件(pem证书和key文件),但是RabbitMQ中用到的是3个文件,需要把一个pem证书拆分为两个文件:ca证书文件和签发出来的域名pem,一般pem文件下面的密钥为ca证书文件。将处理好的3个文件上传到服务器中等待配置。
  3. 然后进入安装RabbitMQ的机器并进入配置文件目录

    cd /etc/rabbitmq/

    vi rabbitmq.conf

    在文件中输入web_stomp.ssl.port       = 15673

    web_stomp.ssl.backlog    = 1024

    web_stomp.ssl.cacertfile = /ssl/ca.pem

    web_stomp.ssl.certfile   = /ssl/xxx.com.pem

    web_stomp.ssl.keyfile    = /ssl/xxx.com.key

    保存即可

  4. 然后最重要的需要重启rabbitmq-server服务,如果有防火墙,得放开15673端口
  5. 然后使用js连接的时候访问这个地址
    wss://rabbitmq.xxx.com:15673/ws
  6. 以上就能使用https/web-stomp了

JS实现连接RabbitMQ

首先需要启动RabbitMQ服务端相关的stomp插件rabbitmq_web_stomp

命令如下:rabbitmq-plugins enable rabbitmq_management rabbitmq_web_stomp rabbitmq_stomp

是通过端口15674以websocket的方式来进行连接的

实现代码如下:载入stomp.js和sockjs-0.3.js

 

<!DOCTYPE html>
<html>  
    <head>  
        <title>WebSocket</title>  
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    </head>  
    <body>  
    <div id="main">  
        <div id="message"></div>  
    </div>  
    </body> 
	<script src="jquery-1.10.2.min.js"></script>
	<!-- stomp协议的客户端脚本 -->
	<script src="stomp.js"></script>
	<!-- SockJS的客户端脚本 -->
	<script src="sockjs-0.3.js"></script>	
    <script type="text/javascript"> 
 
	var ws = new WebSocket('ws://192.168.10.182:15674/ws');
	// 获得Stomp client对象
	var client = Stomp.over(ws);
 
	// SockJS does not support heart-beat: disable heart-beats
	//client.heartbeat.outgoing = 0;
	//client.heartbeat.incoming = 0;
 
	// 定义连接成功回调函数
	var on_connect = function(x) {
		//data.body是接收到的数据
                
          client.subscribe("/exchange/test", function(data) {  
			var msg = data.body;
			$("#message").append("收到数据:" + msg);
		});
	};
 
	// 定义错误时回调函数
	var on_error =  function(err) {
		console.log(err);
	};
 
	// 连接RabbitMQ
	client.connect('admin', 'admin', on_connect, on_error, 'vhosttest');
	console.log(">>>连接上http://192.168.10.182:15674");
	
	</script>  
 </html>

如此就能收到发送到exchange为test的消息了

用到的js文件可在此下载rabbitmq-stomp

 

php调用https

<?php

function curl_get_https($url)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 跳过证书检查
$tmpInfo = curl_exec($curl);
curl_close($curl);
return $tmpInfo;
}

$url = "https://www.baidu.com";

$result = curl_get_https($url);

var_dump($result);

jQuery实现弹出层3秒后自动消失

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery实现弹出层3秒后自动消失</title>
<script type="text/javascript" src="../jquery.js"></script>
</head>

<style>
.loginCoinBox{
position: fixed;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.2);
display: none;
}
.box1{
width: 500px;
height: 500px;
position: fixed;left: 50%; top: 25%;
margin-left: -250px;
border: 1px solid #000000;
}
</style>
<body>
<div class="loginCoinBox">
<div class="box1">
成功
</div>
</div>
<script type="text/javascript">
$(".loginCoinBox").show().delay(3000).hide(300);
</script>
</body>
</html>

apache开启.htaccess及.htaccess的使用方法

1 . 如何让的本地APACHE支持.htaccess 
如何让的本地APACHE支持.htaccess呢?其实只要简单的修改一下apache的httpd.conf设置就让APACHE支持.htaccess了,来看看如何操作 

打开httpd.conf(在那里? APACHE目录的CONF目录里面),用文本编辑器打开后,查找 
(1) 
Options FollowSymLinks 
AllowOverride None 

改为 
Options FollowSymLinks 
AllowOverride All 

(2)去掉下面的注释 
LoadModule rewrite_module modules/mod_rewrite.so 


就好了,修改完后别忘了重启apache哦。

 

2. htaccess 写法 
  Apache中的.htaccess(或者”分布式配置”了针对目录改变配置的方法,即,在特定的文档目录中放置包含或多个指令的,以作用于此目录及其子目录。作为,所能的命令受到限制。***Apache的AllowOverride指令来设置。 

  子目录中的指令会笼盖更高级目录或者主器配置中的指令。 

  .htaccess必需以ASCII模式上传,最好将其权限设置为644。 

  错误文档的定位 

  常用的客户端哀求错误返回代码: 
  401 Authorization Required 
  403 Forbidden 
  404 Not Found 
  405 Method Not Allowed 
  408 Request Timed Out 
  411 Content Length Required 
  412 Precondition Failed 
  413 Request Entity Too Long 
  414 Request URI Too Long 
  415 Unsupported Media Type 

  常见的器错误返回代码: 
  500 Internal Server Error 

  利用.htaccess指定事先制作好的错误提醒页面。一般下,人们专门设立目录,例如errors放置页面。然后再.htaccess中,加入如下的指令: 

  ErrorDocument 404 /errors/notfound.html 
  ErrorDocument 500 /errors/internalerror.html 

  一条指令一行。上述第一条指令的意思是对于404,也找到所的文档的得显示页面为/errors目录下的notfound.html页面。不难看出语法格局为: 

  ErrorDocument 错误代码 /目录名/名.扩展名 

  所提示的很少的话,不必专门制作页面,直接在指令中HTML号了,例如下面例子: 

  ErrorDocument 401 “你权限访问该页面,请抛却!” 

  文档访问的密码保护 

  要利用.htaccess对某个目录下的文档设定访问和对应的密码,首先要做的是生成.htpasswd的文本文档,例如: 

  zheng:y4E7Ep8e7EYV 

  这里密码经由加密,找些工具将密码加密成.htaccess的编码。该文档最好不要放在www目录下,建议放在www根目录文档之外,这样更为安全些。 

  有了授权文档,在.htaccess中加入如下指令了: 

  AuthUserFile .htpasswd的器目录 
  AuthGroupFile /dev/null (授权访问的目录) 
  AuthName EnterPassword 
  AuthType Basic (授权类型) 

  是的主人,应该处处为着想。 —— 雷锋 
  require user wsabstract (允许访问的,但愿表中都允许, require valid-user) 

  注,括号部门为学习添加的注释 

  拒绝来自某个IP的访问  

  例如: 

  order allow,deny 
  deny from 210.10.56.32 
  deny from 219.5.45. 
  allow from all 

  第二行拒绝某个IP,第三行拒绝某个IP段,也219.5.45.0~219.2.45.255 

  想要拒绝人?用deny from all好了。不止用IP,也用域名来设定。 

  保护.htaccess文档 

  在.htaccess来设置目录的密码保护时,它包含了密码的路径。从安全考虑,有必要把.htaccess也保护起来,不让别人看到其中的。虽然用其他做到这点,好比文档的权限。不外,.htaccess本身也能做到,只需加入如下的指令: 

  order allow,deny 
  deny from all 

  URL转向 

  可能对重新规划,将文档了迁移,或者更改了目录。这,来自搜索引擎或者其他链接过来的访问就可能犯错。这种下,如下指令来完成旧的URL自动转向到新的: 

  Redirect /旧目录/旧文档名 新文档的 

  或者整个目录的转向: 

  Redirect 旧目录 新目录 

  改变缺省的首页 

  一般下缺省的首页名有default、index等。不外,有些目录中没出缺省,而是某个特定的名,好比在pmwiki中是 pmwiki.php。这种下,要记住名来访问很麻烦。在.htaccess中等闲的设置新的缺省名: 

  DirectoryIndex 新的缺省名 

  也列出多个,顺序表明它们之间的优先级别,例如: 

  DirectoryIndex filename.html index.cgi index.pl default.htm 

  防止盗链 

  不喜欢别人在的网页上连接的、文档的话,也htaccess的指令来做到。 

  所的指令如下: 

  RewriteEngine on 
  RewriteCond %{ HTTP_REFERER } !^$ 
  RewriteCond %{ HTTP_REFERER } !^http://(www.)?mydomain.com/.*$ [NC] 
  RewriteRule .(gif&line;jpg)$ - [F] 

  觉得让别人的页面开个天窗不好看,那用一张来代替: 

  RewriteEngine on 
  RewriteCond %{ HTTP_REFERER } !^$ 
  RewriteCond %{ HTTP_REFERER } !^http://(www.)?mydomain.com/.*$ [NC] 
  RewriteRule .(gif&line;jpg)$ http://www.mydomain.com/替代名 [R,L] 

移动APP唤起QQ聊天

在APP中打开QQ聊天使用如下代码即可

<a href="mqqwpa://im/chat?chat_type=wpa&uin=422195340&version=1&src_type=web&web_src=oicqzone.com" class="chat_a" >联系客服</a>

在PC网页打开QQ聊天添加如下代码即可

<a href="http://wpa.qq.com/msgrd?v=3&uin=422195340&site=qq&menu=yes" class="chat_a" >联系客服</a>

 

不明白的可以联系我

 

注意:如果在Android WebView中无法跳转的话需要在app中增加代码详情请看我的另一篇文章

Android WebView中跳转第三方APP

一、概述

当你的应用中WebView打开一个H5页面,在这个页面中需要可以打开第三方App页面,通用的跳转方式为Scheme协议Intent协议

Scheme格式

客户端自定义的 URL 作为从一个应用调用另一个的基础,遵循 RFC 1808 (Relative Uniform Resource Locators) 标准。这跟我们常见的网页内容 URL 格式一样。

一个普通的 URL 分为几个部分,scheme、host、relativePath、query。

比如:http://www.baidu.com/s?rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709,这个URL中,scheme 为 http,host 为 www.baidu.com,relativePath 为 /s,query 为 rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709。

一个应用中使用的 URL 例子(该 URL 会调起车辆详情页):uumobile://mobile/carDetail?car_id=123456,其中 scheme 为 uumobile,host 为 mobile,relativePath 为 /carDetail,query 为 car_id=123456。

Intent格式  

intent:
HOST/URI-path // Optional host

Intent;

  package=[string];
  action=[string];
  category=[string];
  component=[string];
  scheme=[string];

end;


举个栗子
```java
intent:
   //scan/
   #Intent;
      package=com.sapp.android;
      scheme=fengye;
   end;
即:
  intent://scan/#Intent;scheme= fengye;package=com.sapp.android;end
  intent://platformapi/startapp?appId=20000013&pwdType=ordinaryPassword&_t=1456301771669#Intent;scheme=alipays;package=com.eg.android.AlipayGphone;end

二、在Webview支持Scheme和intent协议

WebViewClientshouldOverrideUrlLoading方法中实现以下代码:

@Override
public boolean shouldOverrideUrlLoading(WebView view, String newurl) {
    try {
    //处理intent协议
      if (newurl.startsWith("intent://")) {
      Intent intent;
        try {
              intent = Intent.parseUri(newurl, Intent.URI_INTENT_SCHEME);
              intent.addCategory("android.intent.category.BROWSABLE");
              intent.setComponent(null);
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
                    intent.setSelector(null);
               }
               List<ResolveInfo> resolves = context.getPackageManager().queryIntentActivities(intent,0);
               if(resolves.size()>0){
                    startActivityIfNeeded(intent, -1);
               }
               return true;
          } catch (URISyntaxException e) {
               e.printStackTrace();
          }
      }
     // 处理自定义scheme协议
        if (!newurl.startsWith("http")) {
            MyLogUtil.LogI("yxx","处理自定义scheme-->" + newurl);
            try {
               // 以下固定写法
               final Intent intent = new Intent(Intent.ACTION_VIEW,
                        Uri.parse(newurl));
               intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_SINGLE_TOP);
               startActivity(intent);
            } catch (Exception e) {
               // 防止没有安装的情况
               e.printStackTrace();
               ToastManager.showToast("您所打开的第三方App未安装!");
            }
             return true;
         }
    } catch (Exception e) {
        e.printStackTrace();
    }

        return super.shouldOverrideUrlLoading(view, newurl);
}

三、App中支持第三方App或者浏览器跳转自己App

修改Manifest文件,给想要接收跳转的Activity添加<intent-filter>配置,例如:

<activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <!--需要添加下面的intent-filter配置-->
        <intent-filter>
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <data android:scheme="fengye"/>
        </intent-filter>
    </activity>

然后在MainActivityonCreate方法中获取相关传递数据。例如:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent =getIntent();
        Log.e(TAG, "scheme:" +intent.getScheme());
        Uri uri =intent.getData();
        Log.e(TAG, "scheme: "+uri.getScheme());
        Log.e(TAG, "host: "+uri.getHost());
        Log.e(TAG, "port: "+uri.getPort());
        Log.e(TAG, "path: "+uri.getPath());
        Log.e(TAG, "queryString: "+uri.getQuery());
        Log.e(TAG, "queryParameter: "+uri.getQueryParameter("key"));
    }
}

PHP文件上传error的错误类型 – $_FILES[‘file’][‘error’]

假设文件上传字段的名称video,则:

$_FILES['video']['error']有以下几种类型

1、UPLOAD_ERR_OK

其值为 0,没有错误发生,文件上传成功。
 

2、UPLOAD_ERR_INI_SIZE

其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize选项限制的值。
 

3、UPLOAD_ERR_FORM_SIZE

其值为 2,上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。
 

4、UPLOAD_ERR_PARTIAL

其值为 3,文件只有部分被上传。
 

5、UPLOAD_ERR_NO_FILE

其值为 4,没有文件被上传。
 

6、UPLOAD_ERR_NO_TMP_DIR

其值为 6,找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。
 

7、UPLOAD_ERR_CANT_WRITE

其值为 7,文件写入失败。PHP 5.1.0 引进。